diff --git a/converse.js b/converse.js
index ab5c8023c..74e8e1afb 100644
--- a/converse.js
+++ b/converse.js
@@ -9,13 +9,30 @@
/* The following line defines global variables defined elsewhere. */
/*globals jQuery, portal_url*/
-var xmppchat = (function (jarnxmpp, $, console) {
- var ob = jarnxmpp;
- ob.messages = {};
- ob.messages.ClientStorage = (function () {
+
+// AMD/global registrations
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define([
+ 'burry.js/burry'
+ ], function (Burry) {
+ var store = new Burry.Store('collective.xmpp.chat');
+ _.str = require('underscore.string');
+ return factory(jarnxmpp, jQuery, store, _, console);
+ }
+ );
+ } else {
+ // Browser globals
+ var store = new Burry.Store('collective.xmpp.chat');
+ root.xmppchat = factory(jarnxmpp, jQuery, store, _, console || {log: function(){}});
+ }
+}(this, function (jarnxmpp, $, store, _, console) {
+
+ var xmppchat = jarnxmpp;
+ xmppchat.messages = {};
+ xmppchat.messages.ClientStorage = (function () {
// TODO: Messages must be encrypted with a key and salt
methods = {};
-
methods.addMessage = function (jid, msg, direction) {
var bare_jid = Strophe.getBareJidFromJid(jid),
now = new Date().toISOString(),
@@ -33,20 +50,20 @@ var xmppchat = (function (jarnxmpp, $, console) {
return methods;
})();
- ob.messages.getMessages = function (jid, callback) {
+ xmppchat.messages.getMessages = function (jid, callback) {
var bare_jid = Strophe.getBareJidFromJid(jid),
msgs = this.ClientStorage.getMessages(bare_jid);
callback(msgs);
};
- ob.collections = {
+ xmppchat.collections = {
/* 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.
*/
'URI': 'http://www.xmpp.org/extensions/xep-0136.html#ns'
};
- ob.collections.getLastCollection = function (jid, callback) {
+ xmppchat.collections.getLastCollection = function (jid, callback) {
var bare_jid = Strophe.getBareJidFromJid(jid),
iq = $iq({'type':'get'})
.c('list', {'xmlns': this.URI,
@@ -64,7 +81,7 @@ var xmppchat = (function (jarnxmpp, $, console) {
});
};
- ob.collections.getLastMessages = function (jid, callback) {
+ xmppchat.collections.getLastMessages = function (jid, callback) {
var that = this;
this.getLastCollection(jid, function (result) {
// Retrieve the last page of a collection (max 30 elements).
@@ -82,1424 +99,1417 @@ var xmppchat = (function (jarnxmpp, $, console) {
xmppchat.connection.sendIQ(iq, callback);
});
};
- return ob;
-})(jarnxmpp || {}, jQuery, console || {log: function(){}});
+ xmppchat.ChatBox = Backbone.Model.extend({
+ initialize: function () {
+ this.set({
+ 'user_id' : Strophe.getNodeFromJid(this.get('jid')),
+ 'box_id' : hex_sha1(this.get('jid')),
+ 'fullname' : this.get('fullname')
+ });
+ }
+ });
-xmppchat.ChatBox = Backbone.Model.extend({
+ xmppchat.ChatBoxView = Backbone.View.extend({
+ length: 200,
+ tagName: 'div',
+ className: 'chatbox',
- hash: function (str) {
- return hex_sha1(str);
- },
+ events: {
+ 'click .close-chatbox-button': 'closeChat',
+ 'keypress textarea.chat-textarea': 'keyPressed'
+ },
- initialize: function () {
- this.set({
- 'user_id' : Strophe.getNodeFromJid(this.get('jid')),
- 'box_id' : this.hash(this.get('jid')),
- 'fullname' : this.get('fullname')
- });
- }
+ message_template: _.template(
+ '
'),
-});
+ action_template: _.template(
+ ''),
-xmppchat.ChatBoxView = Backbone.View.extend({
- length: 200,
- tagName: 'div',
- className: 'chatbox',
-
- events: {
- 'click .close-chatbox-button': 'closeChat',
- 'keypress textarea.chat-textarea': 'keyPressed'
- },
-
- message_template: _.template(
- ''),
-
- action_template: _.template(
- ''),
-
- appendMessage: function (message) {
- var time,
- now = new Date(),
- minutes = now.getMinutes().toString(),
- list,
- $chat_content,
- match;
- message = message.replace(//g,">").replace(/\"/g,""").replace(/^\s*/, "");
- list = message.match(/\b(http:\/\/www\.\S+\.\w+|www\.\S+\.\w+|http:\/\/(?=[^w]){3}\S+[\.:]\S+)[^ ]+\b/g);
- if (list) {
- for (i = 0; i < list.length; i++) {
- message = message.replace(list[i], ""+ list[i] + "" );
+ appendMessage: function (message) {
+ var time,
+ now = new Date(),
+ minutes = now.getMinutes().toString(),
+ list,
+ $chat_content,
+ match;
+ message = message.replace(//g,">").replace(/\"/g,""").replace(/^\s*/, "");
+ list = message.match(/\b(http:\/\/www\.\S+\.\w+|www\.\S+\.\w+|http:\/\/(?=[^w]){3}\S+[\.:]\S+)[^ ]+\b/g);
+ if (list) {
+ for (i = 0; i < list.length; i++) {
+ message = message.replace(list[i], ""+ list[i] + "" );
+ }
}
- }
- if (minutes.length==1) {minutes = '0'+minutes;}
- time = now.toLocaleTimeString().substring(0,5);
- $chat_content = $(this.el).find('.chat-content');
- $chat_content.find('div.chat-event').remove();
-
- match = message.match(/^\/(.*?)(?: (.*))?$/);
- if ((match) && (match[1] === 'me')) {
- message = message.replace(/^\/me/, '*'+xmppchat.username);
- $chat_content.append(this.action_template({
- 'sender': 'me',
- 'time': time,
- 'message': message,
- 'username': xmppchat.username,
- 'extra_classes': ''
- }));
- } else {
- $chat_content.append(this.message_template({
- 'sender': 'me',
- 'time': time,
- 'message': message,
- 'username': 'me',
- 'extra_classes': ''
- }));
- }
- $chat_content.scrollTop($chat_content[0].scrollHeight);
- },
-
- insertStatusNotification: function (user_id, message) {
- var $chat_content = this.$el.find('.chat-content');
- $chat_content.find('div.chat-event').remove().end()
- .append($('').text(user_id+' '+message));
- $chat_content.scrollTop($chat_content[0].scrollHeight);
- },
-
- messageReceived: function (message) {
- /* XXX: event.mtype should be 'xhtml' for XHTML-IM messages,
- but I only seem to get 'text'.
- */
- var body = $(message).children('body').text(),
- jid = $(message).attr('from'),
- composing = $(message).find('composing'),
- $chat_content = $(this.el).find('.chat-content'),
- user_id = Strophe.getNodeFromJid(jid),
- delayed = $(message).find('delay').length > 0,
- fullname = this.model.get('fullname');
-
- if (xmppchat.xmppstatus.getOwnStatus() === 'offline') {
- // only update the UI if the user is not offline
- return;
- }
- if (!body) {
- if (composing.length > 0) {
- this.insertStatusNotification(fullname, 'is typing');
- return;
- }
- } else {
- xmppchat.messages.ClientStorage.addMessage(jid, body, 'from');
+ if (minutes.length==1) {minutes = '0'+minutes;}
+ time = now.toLocaleTimeString().substring(0,5);
+ $chat_content = $(this.el).find('.chat-content');
$chat_content.find('div.chat-event').remove();
- if (delayed) {
- // XXX: Test properly (for really old messages we somehow need to show
- // their date as well)
- stamp = $(message).find('delay').attr('stamp');
- time = (new Date(stamp)).toLocaleTimeString().substring(0,5);
- } else {
- time = (new Date()).toLocaleTimeString().substring(0,5);
- }
- match = body.match(/^\/(.*?)(?: (.*))?$/);
+
+ match = message.match(/^\/(.*?)(?: (.*))?$/);
if ((match) && (match[1] === 'me')) {
+ message = message.replace(/^\/me/, '*'+xmppchat.username);
$chat_content.append(this.action_template({
- 'sender': 'them',
- 'time': time,
- 'message': body.replace(/^\/me/, '*'+user_id).replace(/
/g, ""),
- 'username': xmppchat.username,
- 'extra_classes': delayed && 'delayed' || ''
- }));
+ 'sender': 'me',
+ 'time': time,
+ 'message': message,
+ 'username': xmppchat.username,
+ 'extra_classes': ''
+ }));
} else {
- $chat_content.append(
- this.message_template({
- 'sender': 'them',
- 'time': time,
- 'message': body.replace(/
/g, ""),
- 'username': fullname,
- 'extra_classes': delayed && 'delayed' || ''
- }));
+ $chat_content.append(this.message_template({
+ 'sender': 'me',
+ 'time': time,
+ 'message': message,
+ 'username': 'me',
+ 'extra_classes': ''
+ }));
}
$chat_content.scrollTop($chat_content[0].scrollHeight);
- }
- },
+ },
- insertClientStoredMessages: function () {
- xmppchat.messages.getMessages(this.model.get('jid'), $.proxy(function (msgs) {
- var $content = this.$el.find('.chat-content');
- for (var i=0; i<_.size(msgs); i++) {
- var msg = msgs[i],
- msg_array = msg.split(' ', 2),
- date = msg_array[0],
- match;
- msg = String(msg).replace(/(.*?\s.*?\s)/, '');
- match = msg.match(/^\/(.*?)(?: (.*))?$/);
- if (msg_array[1] == 'to') {
- if ((match) && (match[1] === 'me')) {
- $content.append(
- this.action_template({
- 'sender': 'me',
- 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
- 'message': msg.replace(/^\/me/, '*'+xmppchat.username),
- 'username': xmppchat.username,
- 'extra_classes': 'delayed'
- }));
- } else {
- $content.append(
- this.message_template({
- 'sender': 'me',
- 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
- 'message': msg,
- 'username': 'me',
- 'extra_classes': 'delayed'
- }));
- }
- } else {
- if ((match) && (match[1] === 'me')) {
- $content.append(
- this.action_template({
- 'sender': 'them',
- 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
- 'message': msg.replace(/^\/me/, '*'+this.model.get('user_id')),
- 'username': this.model.get('fullname'),
- 'extra_classes': 'delayed'
- }));
- } else {
- $content.append(
- this.message_template({
- 'sender': 'them',
- 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
- 'message': msg,
- 'username': this.model.get('fullname'),
- 'extra_classes': 'delayed'
- }));
- }
- }
- }
- }, this));
- },
+ insertStatusNotification: function (user_id, message) {
+ var $chat_content = this.$el.find('.chat-content');
+ $chat_content.find('div.chat-event').remove().end()
+ .append($('').text(user_id+' '+message));
+ $chat_content.scrollTop($chat_content[0].scrollHeight);
+ },
- sendMessage: function (text) {
- // TODO: Also send message to all my own connected resources, so that
- // they can display it as well....
-
- // 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.
- var bare_jid = this.model.get('jid');
- var message = $msg({to: bare_jid, type: 'chat'})
- .c('body').t(text).up()
- .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'});
- xmppchat.connection.send(message);
- xmppchat.messages.ClientStorage.addMessage(bare_jid, text, 'to');
- this.appendMessage(text);
- },
+ messageReceived: function (message) {
+ /* XXX: event.mtype should be 'xhtml' for XHTML-IM messages,
+ but I only seem to get 'text'.
+ */
+ var body = $(message).children('body').text(),
+ jid = $(message).attr('from'),
+ composing = $(message).find('composing'),
+ $chat_content = $(this.el).find('.chat-content'),
+ user_id = Strophe.getNodeFromJid(jid),
+ delayed = $(message).find('delay').length > 0,
+ fullname = this.model.get('fullname');
- keyPressed: function (ev) {
- var $textarea = $(ev.target),
- message,
- notify,
- composing,
- that = this;
-
- if(ev.keyCode == 13) {
- message = $textarea.val();
- $textarea.val('').focus();
- if (message !== '') {
- this.sendMessage(message);
- }
- $(this.el).data('composing', false);
- } else {
- composing = $(this.el).data('composing');
- if (!composing) {
- notify = $msg({'to':this.model.get('jid'), 'type': 'chat'})
- .c('composing', {'xmlns':'http://jabber.org/protocol/chatstates'});
- xmppchat.connection.send(notify);
- $(this.el).data('composing', true);
- }
- }
- },
-
- addChatToCookie: function () {
- var cookie = jQuery.cookie('chats-open-'+xmppchat.username),
- jid = this.model.get('jid'),
- new_cookie,
- open_chats = [];
-
- if (cookie) {
- open_chats = cookie.split('|');
- }
- if (!_.has(open_chats, jid)) {
- // Update the cookie if this new chat is not yet in it.
- open_chats.push(jid);
- new_cookie = open_chats.join('|');
- jQuery.cookie('chats-open-'+xmppchat.username, new_cookie, {path: '/'});
- console.log('updated cookie = ' + new_cookie + '\n');
- }
- },
-
- removeChatFromCookie: function () {
- var cookie = jQuery.cookie('chats-open-'+xmppchat.username),
- open_chats = [],
- new_chats = [];
-
- if (cookie) {
- open_chats = cookie.split('|');
- }
- for (var i=0; i < open_chats.length; i++) {
- if (open_chats[i] != this.model.get('jid')) {
- new_chats.push(open_chats[i]);
- }
- }
- if (new_chats.length) {
- jQuery.cookie('chats-open-'+xmppchat.username, new_chats.join('|'), {path: '/'});
- }
- else {
- jQuery.cookie('chats-open-'+xmppchat.username, null, {path: '/'});
- }
- },
-
- closeChat: function () {
- var that = this;
- $('#'+this.model.get('box_id')).hide('fast', function () {
- that.removeChatFromCookie(that.model.get('id'));
- });
- },
-
- initialize: function (){
- $('body').append($(this.el).hide());
-
- xmppchat.roster.on('change', function (item, changed) {
- if (_.has(changed.changes, 'presence_type')) {
- if (this.$el.is(':visible')) {
- if (item.get('presence_type') === 'offline') {
- this.insertStatusNotification(this.model.get('fullname'), 'has gone offline');
- } else if (item.get('presence_type') === 'away') {
- this.insertStatusNotification(this.model.get('fullname'), 'has gone away');
- } else if ((item.get('presence_type') === 'busy') || (item.get('presence_type') === 'dnd')) {
- this.insertStatusNotification(this.model.get('fullname'), 'is busy');
- } else if (item.get('presence_type') === 'online') {
- this.$el.find('div.chat-event').remove();
- }
- }
- } else if (_.has(changed.changes, 'status')) {
- if (item.get('jid') === this.model.get('jid')) {
- this.$el.find('p.user-custom-message').text(item.get('status'));
- }
- }
- }, this);
- },
-
- template: _.template(
- '' +
- '
<%= fullname %>
' +
- '
X' +
- '
' +
- '
' +
- '' +
- ''),
-
- render: function () {
- $(this.el).attr('id', this.model.get('box_id'));
- $(this.el).html(this.template(this.model.toJSON()));
- this.insertClientStoredMessages();
- return this;
- },
-
- isVisible: function () {
- return $(this.el).is(':visible');
- },
-
- focus: function () {
- $(this.el).find('.chat-textarea').focus();
- return this;
- },
-
- show: function () {
- this.$el.css({'opacity': 0});
- this.$el.css({'display': 'inline'});
- this.$el.animate({
- opacity: '1'
- }, 200);
- return this;
- },
-
- scrolldown: function () {
- var $content = this.$el.find('.chat-content');
- $content.scrollTop($content[0].scrollHeight);
- }
-});
-
-xmppchat.ContactsPanel = Backbone.View.extend({
- el: '#users',
- events: {
- 'click a.add-xmpp-contact': 'toggleContactForm',
- 'submit form.search-xmpp-contact': 'searchContacts',
- 'click a.subscribe-to-user': 'subscribeToContact'
- },
-
- toggleContactForm: function (ev) {
- ev.preventDefault();
- this.$el.find('form.search-xmpp-contact').fadeToggle('medium').find('input.username').focus();
- },
-
- searchContacts: function (ev) {
- ev.preventDefault();
- $.getJSON(portal_url + "/search-users?q=" + $(ev.target).find('input.username').val(), function (data) {
- var $results_el = $('#found-users');
- $(data).each(function (idx, obj) {
- if ($results_el.children().length > 0) {
- $results_el.empty();
- }
- $results_el.append(
- $('')
- .attr('id', 'found-users-'+obj.id)
- .append(
- $('')
- .attr('data-recipient', Strophe.escapeNode(obj.id)+'@'+xmppchat.connection.domain)
- .text(obj.fullname)
- )
- );
- });
- });
- },
-
- subscribeToContact: function (ev) {
- ev.preventDefault();
- var jid = $(ev.target).attr('data-recipient'),
- name = $(ev.target).text();
- xmppchat.connection.roster.add(jid, name, [], function (iq) {
- xmppchat.connection.roster.subscribe(jid);
- });
- $(ev.target).parent().remove();
- $('form.search-xmpp-contact').hide();
- }
-
-});
-
-xmppchat.RoomsPanel = Backbone.View.extend({
- el: '#chatrooms',
- events: {
- 'submit form.add-chatroom': 'createChatRoom',
- 'click a.open-room': 'createChatRoom'
- },
- room_template: _.template(
- '' +
- '' +
- '<%=name%>'),
-
- initialize: function () {
- this.on('update-rooms-list', function (ev) {
- this.updateRoomsList();
- });
- this.trigger('update-rooms-list');
- },
-
- updateRoomsList: function () {
- xmppchat.connection.muc.listRooms(xmppchat.connection.muc_domain, $.proxy(function (iq) {
- var room, name, jid,
- rooms = $(iq).find('query').find('item');
- this.$el.find('#available-chatrooms').find('dd.chatroom').remove();
- if (rooms.length) {
- this.$el.find('#available-chatrooms dt').show();
- } else {
- this.$el.find('#available-chatrooms dt').hide();
- }
- for (var i=0; i div');
- this.contactspanel = new xmppchat.ContactsPanel();
- this.roomspanel = new xmppchat.RoomsPanel();
- this.settingspanel = new xmppchat.SettingsPanel();
- },
-
- render: function () {
- return this;
- }
-});
-
-xmppchat.ChatRoom = xmppchat.ChatBox.extend({
- initialize: function (jid) {
- var nick = Strophe.getNodeFromJid(xmppchat.connection.jid);
- this.set({
- 'id': jid,
- 'name': Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),
- 'nick': Strophe.unescapeNode(Strophe.getNodeFromJid(xmppchat.connection.jid)),
- 'jid': jid,
- 'box_id' : this.hash(jid)
- }, {'silent': true});
- }
-});
-
-
-xmppchat.ChatRoomView = xmppchat.ChatBoxView.extend({
- length: 300,
- tagName: 'div',
- className: 'chatroom',
- events: {
- 'click .close-chatbox-button': 'closeChatRoom',
- 'keypress textarea.chat-textarea': 'keyPressed'
- },
-
- closeChatRoom: function () {
- this.closeChat();
- xmppchat.connection.muc.leave(
- this.model.get('jid'),
- this.model.get('nick'),
- this.onLeave,
- undefined);
- delete xmppchat.chatboxesview.views[this.model.get('jid')];
- xmppchat.chatboxesview.model.remove(this.model.get('jid'));
- this.remove();
- },
-
- keyPressed: function (ev) {
- var $textarea = $(ev.target),
- message,
- notify,
- composing,
- that = this;
-
- if(ev.keyCode == 13) {
- message = $textarea.val();
- message = message.replace(/^\s+|\s+jQuery/g,"");
- $textarea.val('').focus();
- if (message !== '') {
- this.sendGroupMessage(message);
- }
- }
- },
-
- sendGroupMessage: function (body) {
- var match = body.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/);
- var args = null;
- if (match) {
- if (match[1] === "msg") {
- // TODO: Private messages
- } else if (match[1] === "topic") {
- xmppchat.connection.muc.setTopic(this.model.get('jid'), match[2]);
-
- } else if (match[1] === "kick") {
- xmppchat.connection.muc.kick(this.model.get('jid'), match[2]);
-
- } else if (match[1] === "ban") {
- xmppchat.connection.muc.ban(this.model.get('jid'), match[2]);
-
- } else if (match[1] === "op") {
- xmppchat.connection.muc.op(this.model.get('jid'), match[2]);
-
- } else if (match[1] === "deop") {
- xmppchat.connection.muc.deop(this.model.get('jid'), match[2]);
- } else {
- this.last_msgid = xmppchat.connection.muc.groupchat(this.model.get('jid'), body);
- }
- } else {
- this.last_msgid = xmppchat.connection.muc.groupchat(this.model.get('jid'), body);
- }
- },
-
- template: _.template(
- '' +
- '
<%= name %>
' +
- '
X' +
- '
' +
- '
' +
- '' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
'),
-
- initialize: function () {
- xmppchat.connection.muc.join(
- this.model.get('jid'),
- this.model.get('nick'),
- $.proxy(this.onMessage, this),
- $.proxy(this.onPresence, this),
- $.proxy(this.onRoster, this));
- },
-
- onLeave: function () {
- var controlboxview = xmppchat.chatboxesview.views.controlbox;
- if (controlboxview) {
- controlboxview.roomspanel.trigger('update-rooms-list');
- }
- },
-
- onPresence: function (presence, room) {
- var nick = room.nick,
- from = $(presence).attr('from');
- if ($(presence).attr('type') !== 'error') {
- // check for status 110 to see if it's our own presence
- if ($(presence).find("status[code='110']").length > 0) {
- // check if server changed our nick
- if ($(presence).find("status[code='210']").length > 0) {
- this.model.set({'nick': Strophe.getResourceFromJid(from)});
+ if (!body) {
+ if (composing.length > 0) {
+ this.insertStatusNotification(fullname, 'is typing');
+ return;
}
- }
- }
- return true;
- },
-
- onMessage: function (message) {
- var body = $(message).children('body').text(),
- jid = $(message).attr('from'),
- composing = $(message).find('composing'),
- $chat_content = $(this.el).find('.chat-content'),
- sender = Strophe.unescapeNode(Strophe.getResourceFromJid(jid)),
- subject = $(message).children('subject').text();
-
- if (subject) {
- this.$el.find('.chatroom-topic').text(subject);
- }
- if (!body) {
- if (composing.length > 0) {
- this.insertStatusNotification(sender, 'is typing');
- return true;
- }
- } else {
- if (sender === this.model.get('nick')) {
- this.appendMessage(body);
} else {
+ xmppchat.messages.ClientStorage.addMessage(jid, body, 'from');
$chat_content.find('div.chat-event').remove();
-
+ if (delayed) {
+ // XXX: Test properly (for really old messages we somehow need to show
+ // their date as well)
+ stamp = $(message).find('delay').attr('stamp');
+ time = (new Date(stamp)).toLocaleTimeString().substring(0,5);
+ } else {
+ time = (new Date()).toLocaleTimeString().substring(0,5);
+ }
match = body.match(/^\/(.*?)(?: (.*))?$/);
if ((match) && (match[1] === 'me')) {
- body = body.replace(/^\/me/, '*'+sender);
- $chat_content.append(
- this.action_template({
- 'sender': 'room',
- 'time': (new Date()).toLocaleTimeString().substring(0,5),
- 'message': body,
- 'username': sender,
- 'extra_classes': ($(message).find('delay').length > 0) && 'delayed' || ''
+ $chat_content.append(this.action_template({
+ 'sender': 'them',
+ 'time': time,
+ 'message': body.replace(/^\/me/, '*'+user_id).replace(/
/g, ""),
+ 'username': xmppchat.username,
+ 'extra_classes': delayed && 'delayed' || ''
}));
} else {
$chat_content.append(
this.message_template({
- 'sender': 'room',
- 'time': (new Date()).toLocaleTimeString().substring(0,5),
- 'message': body,
- 'username': sender,
- 'extra_classes': ($(message).find('delay').length > 0) && 'delayed' || ''
+ 'sender': 'them',
+ 'time': time,
+ 'message': body.replace(/
/g, ""),
+ 'username': fullname,
+ 'extra_classes': delayed && 'delayed' || ''
}));
}
$chat_content.scrollTop($chat_content[0].scrollHeight);
}
- }
- return true;
- },
+ },
- onRoster: function (roster, room) {
- var controlboxview = xmppchat.chatboxesview.views['controlbox'];
- if (controlboxview) {
- controlboxview.roomspanel.trigger('update-rooms-list');
- }
- this.$el.find('.participant-list').empty();
- for (var i=0; i<_.size(roster); i++) {
- this.$el.find('.participant-list').append('' + Strophe.unescapeNode(_.keys(roster)[i]) + '');
- }
- return true;
- },
-
- show: function () {
- this.$el.css({'opacity': 0});
- this.$el.css({'display': 'inline'});
- this.$el.animate({
- opacity: '1'
- }, 200);
- return this;
- },
-
- render: function () {
- $(this.el).attr('id', this.model.get('box_id'));
- $(this.el).html(this.template(this.model.toJSON()));
- return this;
- }
-});
-
-xmppchat.ChatBoxes = Backbone.Collection.extend();
-
-xmppchat.ChatBoxesView = Backbone.View.extend({
- el: '#collective-xmpp-chat-data',
-
- restoreOpenChats: function () {
- var cookie = jQuery.cookie('chats-open-'+xmppchat.username),
- open_chats = [],
- that = this;
-
- jQuery.cookie('chats-open-'+xmppchat.username, null, {path: '/'});
- if (cookie) {
- open_chats = cookie.split('|');
- if (_.indexOf(open_chats, 'controlbox') != -1) {
- this.renderChat('controlbox');
- }
- _.each(open_chats, $.proxy(function (jid) {
- if (jid != 'controlbox') {
- if (_.str.include(jid, xmppchat.connection.muc_domain)) {
- this.renderChat(jid);
+ insertClientStoredMessages: function () {
+ xmppchat.messages.getMessages(this.model.get('jid'), $.proxy(function (msgs) {
+ var $content = this.$el.find('.chat-content');
+ for (var i=0; i<_.size(msgs); i++) {
+ var msg = msgs[i],
+ msg_array = msg.split(' ', 2),
+ date = msg_array[0],
+ match;
+ msg = String(msg).replace(/(.*?\s.*?\s)/, '');
+ match = msg.match(/^\/(.*?)(?: (.*))?$/);
+ if (msg_array[1] == 'to') {
+ if ((match) && (match[1] === 'me')) {
+ $content.append(
+ this.action_template({
+ 'sender': 'me',
+ 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
+ 'message': msg.replace(/^\/me/, '*'+xmppchat.username),
+ 'username': xmppchat.username,
+ 'extra_classes': 'delayed'
+ }));
+ } else {
+ $content.append(
+ this.message_template({
+ 'sender': 'me',
+ 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
+ 'message': msg,
+ 'username': 'me',
+ 'extra_classes': 'delayed'
+ }));
+ }
} else {
- // XXX: Can this be optimised somehow? Would be nice to get
- // fullnames from xmppchat.Roster but it's not yet
- // populated at this stage...
- $.getJSON(portal_url + "/xmpp-userinfo?user_id=" + Strophe.getNodeFromJid(jid), function (data) {
- that.renderChat(jid, data.fullname);
- });
+ if ((match) && (match[1] === 'me')) {
+ $content.append(
+ this.action_template({
+ 'sender': 'them',
+ 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
+ 'message': msg.replace(/^\/me/, '*'+this.model.get('user_id')),
+ 'username': this.model.get('fullname'),
+ 'extra_classes': 'delayed'
+ }));
+ } else {
+ $content.append(
+ this.message_template({
+ 'sender': 'them',
+ 'time': new Date(Date.parse(date)).toLocaleTimeString().substring(0,5),
+ 'message': msg,
+ 'username': this.model.get('fullname'),
+ 'extra_classes': 'delayed'
+ }));
+ }
}
}
}, this));
- }
- },
-
- isChatRoom: function (jid) {
- return Strophe.getDomainFromJid(jid) === xmppchat.connection.muc_domain;
- },
-
- renderChat: function (jid, name) {
- var box, view;
- if (jid === 'controlbox') {
- box = new xmppchat.ControlBox({'id': jid, 'jid': jid});
- view = new xmppchat.ControlBoxView({
- model: box
- });
- } else {
- if (this.isChatRoom(jid)) {
- box = new xmppchat.ChatRoom(jid);
- view = new xmppchat.ChatRoomView({
- 'model': box
- });
+ },
+
+ sendMessage: function (text) {
+ // TODO: Also send message to all my own connected resources, so that
+ // they can display it as well....
+
+ // 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.
+ var bare_jid = this.model.get('jid');
+ var message = $msg({to: bare_jid, type: 'chat'})
+ .c('body').t(text).up()
+ .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'});
+ xmppchat.connection.send(message);
+ xmppchat.messages.ClientStorage.addMessage(bare_jid, text, 'to');
+ this.appendMessage(text);
+ },
+
+ keyPressed: function (ev) {
+ var $textarea = $(ev.target),
+ message,
+ notify,
+ composing,
+ that = this;
+
+ if(ev.keyCode == 13) {
+ message = $textarea.val();
+ $textarea.val('').focus();
+ if (message !== '') {
+ this.sendMessage(message);
+ }
+ $(this.el).data('composing', false);
} else {
- box = new xmppchat.ChatBox({'id': jid, 'jid': jid, 'fullname': name});
- view = new xmppchat.ChatBoxView({
- model: box
- });
- }
- }
- this.views[jid] = view.render();
- view.$el.appendTo(this.$el);
- this.options.model.add(box);
- return view;
- },
-
- closeChat: function (jid) {
- var view = this.views[jid];
- if (view) {
- view.closeChat();
- }
- },
-
- openChat: function (jid, name) {
- if (!this.model.get(jid)) {
- this.renderChat(jid, name);
- } else {
- this.showChat(jid);
- }
- },
-
- showChat: function (jid) {
- var view = this.views[jid];
- if (view.isVisible()) {
- view.focus();
- } else {
- view.show();
- if (jid !== 'controlbox') {
- view.scrolldown();
- view.focus();
- }
- view.addChatToCookie();
- }
- return view;
- },
-
- messageReceived: function (message) {
- var jid = $(message).attr('from'),
- bare_jid = Strophe.getBareJidFromJid(jid),
- resource = Strophe.getResourceFromJid(jid),
- view = this.views[bare_jid],
- fullname;
-
- if (!view) {
- if (xmppchat.roster.get(bare_jid)) {
- fullname = xmppchat.roster.get(bare_jid).get('fullname');
- view = this.renderChat(bare_jid, fullname);
- } else {
- $.getJSON(portal_url + "/xmpp-userinfo?user_id=" + Strophe.getNodeFromJid(bare_jid), $.proxy(function (data) {
- view = this.renderChat(bare_jid, data.fullname);
- view.messageReceived(message);
- xmppchat.roster.addResource(bare_jid, resource);
- }, this));
- return;
- }
- }
- view.messageReceived(message);
- xmppchat.roster.addResource(bare_jid, resource);
- },
-
- initialize: function () {
- this.options.model.on("add", function (item) {
- this.showChat(item.get('id'));
- }, this);
-
- this.views = {};
- this.restoreOpenChats();
- }
-});
-
-
-xmppchat.RosterItem = Backbone.Model.extend({
-
- initialize: function (jid, subscription, ask, name) {
- var user_id = Strophe.getNodeFromJid(jid);
- if (!name) {
- name = user_id;
- }
- this.set({
- 'id': jid,
- 'jid': jid,
- 'ask': ask,
- 'bare_jid': Strophe.getBareJidFromJid(jid),
- 'user_id': user_id,
- 'subscription': subscription,
- 'fullname': name,
- 'resources': [],
- 'presence_type': 'offline',
- 'status': 'offline'
- }, {'silent': true});
- }
-});
-
-
-xmppchat.RosterItemView = Backbone.View.extend({
- tagName: 'dd',
-
- openChat: function () {
- xmppchat.chatboxesview.openChat(this.model.get('jid'), this.model.get('fullname'));
- },
-
- removeContact: function () {
- var that = this;
- $("").dialog({
- title: 'Are you sure you want to remove this contact?',
- dialogClass: 'remove-xmpp-contact-dialog',
- resizable: false,
- width: 200,
- position: {
- my: 'center',
- at: 'center',
- of: '#controlbox'
- },
- modal: true,
- buttons: {
- "Remove": function() {
- var bare_jid = that.model.get('bare_jid');
- $(this).dialog( "close" );
- xmppchat.connection.roster.unauthorize(that.model.get('jid'));
- xmppchat.roster.remove(bare_jid);
- xmppchat.connection.roster.remove(bare_jid);
- },
- "Cancel": function() {
- $(this).dialog( "close" );
+ composing = $(this.el).data('composing');
+ if (!composing) {
+ notify = $msg({'to':this.model.get('jid'), 'type': 'chat'})
+ .c('composing', {'xmlns':'http://jabber.org/protocol/chatstates'});
+ xmppchat.connection.send(notify);
+ $(this.el).data('composing', true);
}
}
- });
- },
+ },
- acceptRequest: function () {
- var jid = this.model.get('jid');
- xmppchat.connection.roster.authorize(jid);
- xmppchat.connection.roster.add(jid, this.model.get('fullname'), [], function (iq) {
- xmppchat.connection.roster.subscribe(jid);
- }, this);
- },
+ addChatToCookie: function () {
+ var cookie = jQuery.cookie('chats-open-'+xmppchat.username),
+ jid = this.model.get('jid'),
+ new_cookie,
+ open_chats = [];
- declineRequest: function () {
- var that = this;
- xmppchat.connection.roster.unauthorize(this.model.get('jid'));
- that.trigger('decline-request', that.model);
- },
-
- template: _.template(
- '<%= fullname %>' +
- ''),
-
- pending_template: _.template(
- '<%= fullname %>' +
- ''),
-
- request_template: _.template('<%= fullname %>' +
- '' +
- '' +
- ''),
-
- render: function () {
- var item = this.model,
- ask = item.get('ask'),
- that = this,
- subscription = item.get('subscription');
-
- $(this.el).addClass(item.get('presence_type')).attr('id', 'online-users-'+item.get('user_id'));
-
- if (ask === 'subscribe') {
- this.$el.addClass('pending-xmpp-contact');
- $(this.el).html(this.pending_template(item.toJSON()));
- } else if (ask === 'request') {
- this.$el.addClass('requesting-xmpp-contact');
- $(this.el).html(this.request_template(item.toJSON()));
- this.$el.delegate('button.accept-xmpp-request', 'click', function (ev) {
- ev.preventDefault();
- that.acceptRequest();
- });
- this.$el.delegate('button.decline-xmpp-request', 'click', function (ev) {
- ev.preventDefault();
- that.declineRequest();
- });
- xmppchat.chatboxesview.openChat('controlbox');
- } else if (subscription === 'both') {
- this.$el.addClass('current-xmpp-contact');
- this.$el.html(this.template(item.toJSON()));
- this.$el.delegate('a.open-chat', 'click', function (ev) {
- ev.preventDefault();
- that.openChat();
- });
- }
-
- // Event handlers
- this.$el.delegate('a.remove-xmpp-contact','click', function (ev) {
- ev.preventDefault();
- that.removeContact();
- });
- return this;
- },
-
- initialize: function () {
- this.options.model.on('change', function (item, changed) {
- if (_.has(changed.changes, 'presence_type')) {
- $(this.el).attr('class', item.changed.presence_type);
+ if (cookie) {
+ open_chats = cookie.split('|');
}
- }, this);
- }
-});
+ if (!_.has(open_chats, jid)) {
+ // Update the cookie if this new chat is not yet in it.
+ open_chats.push(jid);
+ new_cookie = open_chats.join('|');
+ jQuery.cookie('chats-open-'+xmppchat.username, new_cookie, {path: '/'});
+ console.log('updated cookie = ' + new_cookie + '\n');
+ }
+ },
+ removeChatFromCookie: function () {
+ var cookie = jQuery.cookie('chats-open-'+xmppchat.username),
+ open_chats = [],
+ new_chats = [];
-xmppchat.Roster = (function (_, $, console) {
- var ob = {},
- Collection = Backbone.Collection.extend({
- model: xmppchat.RosterItem,
- stropheRoster: xmppchat.connection.roster,
-
- initialize: function () {
- this._connection = xmppchat.connection;
- },
-
- comparator : function (rosteritem) {
- var presence_type = rosteritem.get('presence_type'),
- rank = 4;
- switch(presence_type) {
- case 'offline':
- rank = 4;
- break;
- case 'unavailable':
- rank = 3;
- break;
- case 'away':
- rank = 2;
- break;
- case 'busy':
- rank = 1;
- break;
- case 'dnd':
- rank = 1;
- break;
- case 'online':
- rank = 0;
- break;
+ if (cookie) {
+ open_chats = cookie.split('|');
+ }
+ for (var i=0; i < open_chats.length; i++) {
+ if (open_chats[i] != this.model.get('jid')) {
+ new_chats.push(open_chats[i]);
}
- return rank;
- },
+ }
+ if (new_chats.length) {
+ jQuery.cookie('chats-open-'+xmppchat.username, new_chats.join('|'), {path: '/'});
+ }
+ else {
+ jQuery.cookie('chats-open-'+xmppchat.username, null, {path: '/'});
+ }
+ },
- isSelf: function (jid) {
- return (Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(xmppchat.connection.jid));
- },
+ closeChat: function () {
+ var that = this;
+ $('#'+this.model.get('box_id')).hide('fast', function () {
+ that.removeChatFromCookie(that.model.get('id'));
+ });
+ },
- getRoster: function () {
- return xmppchat.connection.roster.get();
- },
+ initialize: function (){
+ $('body').append($(this.el).hide());
- getItem: function (id) {
- return Backbone.Collection.prototype.get.call(this, id);
- },
-
- addRosterItem: function (jid, subscription, ask, name) {
- var model = new xmppchat.RosterItem(jid, subscription, ask, name);
- this.add(model);
- },
-
- addResource: function (bare_jid, resource) {
- var item = this.getItem(bare_jid),
- resources;
- if (item) {
- resources = item.get('resources');
- if (resources) {
- if (_.indexOf(resources, resource) == -1) {
- resources.push(resource);
- item.set({'resources': resources});
+ xmppchat.roster.on('change', function (item, changed) {
+ if (_.has(changed.changes, 'presence_type')) {
+ if (this.$el.is(':visible')) {
+ if (item.get('presence_type') === 'offline') {
+ this.insertStatusNotification(this.model.get('fullname'), 'has gone offline');
+ } else if (item.get('presence_type') === 'away') {
+ this.insertStatusNotification(this.model.get('fullname'), 'has gone away');
+ } else if ((item.get('presence_type') === 'busy') || (item.get('presence_type') === 'dnd')) {
+ this.insertStatusNotification(this.model.get('fullname'), 'is busy');
+ } else if (item.get('presence_type') === 'online') {
+ this.$el.find('div.chat-event').remove();
}
- } else {
- item.set({'resources': [resource]});
+ }
+ } else if (_.has(changed.changes, 'status')) {
+ if (item.get('jid') === this.model.get('jid')) {
+ this.$el.find('p.user-custom-message').text(item.get('status'));
}
}
- },
-
- removeResource: function (bare_jid, resource) {
- var item = this.getItem(bare_jid),
- resources,
- idx;
- if (item) {
- resources = item.get('resources');
- idx = _.indexOf(resources, resource);
- if (idx !== -1) {
- resources.splice(idx, 1);
- item.set({'resources': resources});
- return resources.length;
- }
- }
- return 0;
- },
-
- clearResources: function (bare_jid) {
- var item = this.getItem(bare_jid);
- if (item) {
- item.set({'resources': []});
- }
- },
-
- getTotalResources: function (bare_jid) {
- var item = this.getItem(bare_jid);
- if (item) {
- return _.size(item.get('resources'));
- }
- },
-
- getNumOnlineContacts: function () {
- var count = 0;
- for (var i=0; i 0)&&(status_message.text())) {
- model = ob.getItem(bare_jid);
- model.set({'status': status_message.text()});
- }
-
- if ((presence_type === 'error') ||
- (presence_type === 'subscribed') ||
- (presence_type === 'unsubscribe')) {
- return true;
- } else if (presence_type === 'subscribe') {
- item = ob.getItem(bare_jid);
- if ((item) && (item.get('subscription') != 'none')) {
- xmppchat.connection.roster.authorize(bare_jid);
- } else {
- $.getJSON(portal_url + "/xmpp-userinfo?user_id=" + Strophe.getNodeFromJid(jid), function (data) {
- ob.addRosterItem(bare_jid, 'none', 'request', data.fullname);
- });
- }
- } else if (presence_type === 'unsubscribed') {
- /* Upon receiving the presence stanza of type "unsubscribed",
- * the user SHOULD acknowledge receipt of that subscription state
- * notification by sending a presence stanza of type "unsubscribe"
- * this step lets the user's server know that it MUST no longer
- * send notification of the subscription state change to the user.
- */
- xmppchat.xmppstatus.sendPresence('unsubscribe');
- if (xmppchat.connection.roster.findItem(bare_jid)) {
- xmppchat.roster.remove(bare_jid);
- xmppchat.connection.roster.remove(bare_jid);
- }
- } else {
- if ((presence_type === undefined) && (show)) {
- if (show.text() === 'chat') {
- presence_type = 'online';
- } else if (show.text() === 'dnd') {
- presence_type = 'busy';
- } else if (show.text() === 'xa') {
- presence_type = 'offline';
- } else {
- presence_type = show.text();
- }
- }
-
- if ((presence_type !== 'offline')&&(presence_type !== 'unavailable')) {
- ob.addResource(bare_jid, resource);
- model = ob.getItem(bare_jid);
- model.set({'presence_type': presence_type});
- } else {
- if (ob.removeResource(bare_jid, resource) === 0) {
- model = ob.getItem(bare_jid);
- model.set({'presence_type': presence_type});
- }
- }
- }
- return true;
- };
- return ob;
-});
-
-
-xmppchat.RosterView= (function (roster, _, $, console) {
- var View = Backbone.View.extend({
- el: $('#xmppchat-roster'),
- model: roster,
- rosteritemviews: {},
-
- initialize: function () {
- this.model.on("add", function (item) {
- var view = new xmppchat.RosterItemView({model: item});
- this.rosteritemviews[item.id] = view;
- if (item.get('ask') === 'request') {
- view.on('decline-request', function (item) {
- this.model.remove(item.id);
- }, this);
- }
- this.render();
- }, this);
-
- this.model.on('change', function (item) {
- this.render();
- }, this);
-
- this.model.on("remove", function (item) {
- delete this.rosteritemviews[item.id];
- this.render();
}, this);
},
- template: _.template('Contact requests' +
- 'My contacts' +
- 'Pending contacts'),
+ template: _.template(
+ '' +
+ '
<%= fullname %>
' +
+ '
X' +
+ '
' +
+ '
' +
+ '' +
+ ''),
render: function () {
- this.$el.empty().html(this.template());
- var models = this.model.sort().models,
- children = $(this.el).children(),
- my_contacts = this.$el.find('#xmpp-contacts').hide(),
- contact_requests = this.$el.find('#xmpp-contact-requests').hide(),
- pending_contacts = this.$el.find('#pending-xmpp-contacts').hide();
+ $(this.el).attr('id', this.model.get('box_id'));
+ $(this.el).html(this.template(this.model.toJSON()));
+ this.insertClientStoredMessages();
+ return this;
+ },
- for (var i=0; i 0) {
- h.show();
- }
- });
- $('#online-count').text(this.model.getNumOnlineContacts());
+ focus: function () {
+ $(this.el).find('.chat-textarea').focus();
+ return this;
+ },
+
+ show: function () {
+ this.$el.css({'opacity': 0});
+ this.$el.css({'display': 'inline'});
+ this.$el.animate({
+ opacity: '1'
+ }, 200);
+ return this;
+ },
+
+ scrolldown: function () {
+ var $content = this.$el.find('.chat-content');
+ $content.scrollTop($content[0].scrollHeight);
}
});
- var view = new View();
- return view;
-});
-xmppchat.XMPPStatus = Backbone.Model.extend({
+ xmppchat.ContactsPanel = Backbone.View.extend({
+ el: '#users',
+ events: {
+ 'click a.add-xmpp-contact': 'toggleContactForm',
+ 'submit form.search-xmpp-contact': 'searchContacts',
+ 'click a.subscribe-to-user': 'subscribeToContact'
+ },
- sendPresence: function (type) {
- if (type === undefined) {
- type = this.getOwnStatus() || 'online';
+ toggleContactForm: function (ev) {
+ ev.preventDefault();
+ this.$el.find('form.search-xmpp-contact').fadeToggle('medium').find('input.username').focus();
+ },
+
+ searchContacts: function (ev) {
+ ev.preventDefault();
+ $.getJSON(portal_url + "/search-users?q=" + $(ev.target).find('input.username').val(), function (data) {
+ var $results_el = $('#found-users');
+ $(data).each(function (idx, obj) {
+ if ($results_el.children().length > 0) {
+ $results_el.empty();
+ }
+ $results_el.append(
+ $('')
+ .attr('id', 'found-users-'+obj.id)
+ .append(
+ $('')
+ .attr('data-recipient', Strophe.escapeNode(obj.id)+'@'+xmppchat.connection.domain)
+ .text(obj.fullname)
+ )
+ );
+ });
+ });
+ },
+
+ subscribeToContact: function (ev) {
+ ev.preventDefault();
+ var jid = $(ev.target).attr('data-recipient'),
+ name = $(ev.target).text();
+ xmppchat.connection.roster.add(jid, name, [], function (iq) {
+ xmppchat.connection.roster.subscribe(jid);
+ });
+ $(ev.target).parent().remove();
+ $('form.search-xmpp-contact').hide();
}
- xmppchat.connection.send($pres({'type':type}));
- },
- getOwnStatus: function () {
- return store.get(xmppchat.connection.bare_jid+'-xmpp-status');
- },
+ });
- setOwnStatus: function (value) {
- this.sendPresence(value);
- store.set(xmppchat.connection.bare_jid+'-xmpp-status', value);
- },
+ xmppchat.RoomsPanel = Backbone.View.extend({
+ el: '#chatrooms',
+ events: {
+ 'submit form.add-chatroom': 'createChatRoom',
+ 'click a.open-room': 'createChatRoom'
+ },
+ room_template: _.template(
+ '' +
+ '' +
+ '<%=name%>'),
- setCustomStatus: function (presence_type, custom_status) {
- xmppchat.connection.send($pres({'type':presence_type}).c('status').t(custom_status));
- }
+ initialize: function () {
+ this.on('update-rooms-list', function (ev) {
+ this.updateRoomsList();
+ });
+ this.trigger('update-rooms-list');
+ },
-});
+ updateRoomsList: function () {
+ xmppchat.connection.muc.listRooms(xmppchat.connection.muc_domain, $.proxy(function (iq) {
+ var room, name, jid,
+ rooms = $(iq).find('query').find('item');
+ this.$el.find('#available-chatrooms').find('dd.chatroom').remove();
+ if (rooms.length) {
+ this.$el.find('#available-chatrooms dt').show();
+ } else {
+ this.$el.find('#available-chatrooms dt').hide();
+ }
+ for (var i=0; i' +
- '" placeholder="Custom status"/>' +
- '' +
- ''),
-
- status_template: _.template(
- ''),
-
-
- changeStatusMessage: function (ev) {
- ev.preventDefault();
- var chat_status = $(ev.target).find('input').attr('value');
- var presence_type = this.model.getOwnStatus() || 'I am offline';
- $(this.el).find('#fancy-xmpp-status-select').html(
- this.status_template({
- 'chat_status': chat_status,
- 'presence_type': presence_type
- }));
- this.model.setCustomStatus(presence_type, chat_status);
- },
-
- renderStatusChangeForm: function (ev) {
- ev.preventDefault();
- var chat_status = this.model.getOwnStatus() || 'offline';
- var input = this.change_status_message_template({'chat_status': chat_status});
- this.$el.find('.xmpp-status').replaceWith(input);
- this.$el.find('.custom-xmpp-status').focus().focus();
- },
-
- setOwnStatus: function (ev) {
- ev.preventDefault();
- var $el = $(ev.target).find('span'),
- value = $el.text();
-
- $(this.el).find('#fancy-xmpp-status-select').html(
- this.status_template({
- 'chat_status': 'I am ' + value,
- 'presence_type': value
- }));
- $(this.el).find(".dropdown dd ul").hide();
- $(this.el).find("#source").val($($el).find("span.value").html());
- this.model.setOwnStatus(value);
- },
-
- choose_template: _.template(
- '' +
- '' +
- '' +
- '
'),
-
- option_template: _.template(
- '' +
- '' +
- '<%= text %>' +
- '<%= value %>' +
- '' +
- ''),
-
- initialize: function () {
- var $select = $(this.el).find('select#select-xmpp-status'),
- presence_type = this.model.getOwnStatus() || 'offline',
- options = $('option', $select),
- that = this;
-
- $(this.el).html(this.choose_template());
- $(this.el).find('#fancy-xmpp-status-select')
- .html(this.status_template({
- 'chat_status': "I am " + presence_type,
- 'presence_type': presence_type
- }));
-
- // iterate through all the