Refactor: The controlbox is now rendered via JS template.

- Removes the need for JQueryUI
This commit is contained in:
JC Brand 2012-10-25 12:36:37 +02:00
parent 07ca5d3506
commit a3f54321aa

View File

@ -9,27 +9,48 @@
/* The following line defines global variables defined elsewhere. */ /* The following line defines global variables defined elsewhere. */
/*globals jQuery, portal_url*/ /*globals jQuery, portal_url*/
// AMD/global registrations // AMD/global registrations
(function (root, factory) { (function (root, factory) {
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
require.config({
// paths: {
// "patterns": "Libraries/Patterns"
// },
// define module dependencies for modules not using define
shim: {
'Libraries/backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: [
'Libraries/underscore',
'jquery'],
//Once loaded, use the global 'Backbone' as the
//module value.
exports: 'Backbone'
},
'Libraries/strophe.muc': {
deps: ['Libraries/strophe', 'jquery']
},
'Libraries/strophe.roster': {
deps: ['Libraries/strophe', 'jquery']
}
}
});
define([ define([
'Libraries/burry.js/burry', "Libraries/burry.js/burry",
"Libraries/jquery.gritter.min",
"Libraries/jquery.cookie",
"Libraries/jquery.ba-dotimeout.min",
"Libraries/underscore", "Libraries/underscore",
"Libraries/underscore.string/lib/underscore.string", "Libraries/sjcl",
"Libraries/backbone", "Libraries/backbone",
"Libraries/strophe",
"Libraries/strophe.muc", "Libraries/strophe.muc",
"Libraries/strophe.roster", "Libraries/strophe.roster"
"Libraries/diff_match_patch", ], function (Burry, _s) {
"Libraries/jarnxmpp.core.handlers",
"Libraries/jarnxmpp.collaboration.protocol",
"Libraries/jarnxmpp.collaboration.collaborate"
], function (Burry) {
var store = new Burry.Store('collective.xmpp.chat'); var store = new Burry.Store('collective.xmpp.chat');
// Init underscore.str
_.str = _s;
// Use Mustache style syntax for variable interpolation // Use Mustache style syntax for variable interpolation
_.templateSettings = { _.templateSettings = {
evaluate : /\{\[([\s\S]+?)\]\}/g, evaluate : /\{\[([\s\S]+?)\]\}/g,
@ -561,20 +582,87 @@
}); });
xmppchat.ControlBoxView = xmppchat.ChatBoxView.extend({ xmppchat.ControlBoxView = xmppchat.ChatBoxView.extend({
el: '#controlbox', // XXX: Options for the (still to be done) 'settings' tab:
// * Show offline users
// * Auto-open chatbox when a message was received.
tagName: 'div',
className: 'chatbox',
id: 'controlbox',
events: { events: {
'click a.close-controlbox-button': 'closeChat' 'click a.close-controlbox-button': 'closeChat',
'click ul.controlbox-tabs li a': 'switchTab'
},
template: _.template(
'<div class="chat-head oc-chat-head">'+
'<ul class="controlbox-tabs">'+
'<li><a class="s current" href="#users">Contacts</a></li>'+
'<li><a class="s" href="#chatrooms">Rooms</a></li>'+
'<!--<li><a class="s" href="#settings">Config</a></li>-->'+
'</ul>'+
'<a href="javascript:void(0)" class="close-controlbox-button">X</a>'+
'</div>'+
'<!-- tab "panes" -->'+
'<div class="panes">'+
'<div id="users" class="oc-chat-content">'+
'<form class="set-xmpp-status" action="" method="post">'+
'<span id="xmpp-status-holder">'+
'<select id="select-xmpp-status">'+
'<option value="online">Online</option>'+
'<option value="busy">Busy</option>'+
'<option value="away">Away</option>'+
'<option value="offline">Offline</option>'+
'</select>'+
'</span>'+
'</form>'+
'<div class="add-xmpp-contact">'+
'<a class="add-xmpp-contact" href="#" title="Click to search for new users to add as chat contacts">Add a contact</a>'+
'<form class="search-xmpp-contact" style="display:none">'+
'<input type="text" name="identifier" class="username" placeholder="Contact name"/>'+
'<button type="submit">Search</button>'+
'<ul id="found-users"></ul>'+
'</form>'+
'</div>'+
'<dl id="xmppchat-roster"></dl>'+
'</div>'+
'<div id="chatrooms" style="display:None">'+
'<form class="add-chatroom" action="" method="post">'+
'<input type="text" name="chatroom" class="new-chatroom-name" placeholder="Chat room name"/>'+
'<button type="submit">Join</button>'+
'</form>'+
'<dl id="available-chatrooms">'+
'<dt>Available chatrooms</dt>'+
'</dl>'+
'</div>'+
'</div>'
),
switchTab: function (ev) {
ev.preventDefault();
var $tab = $(ev.target),
$sibling = $tab.parent().siblings('li').children('a'),
$tab_panel = $($tab.attr('href')),
$sibling_panel = $($sibling.attr('href'));
$sibling_panel.fadeOut('fast', function () {
$sibling.removeClass('current');
$tab.addClass('current');
$tab_panel.fadeIn('fast', function () {
});
});
}, },
initialize: function () { initialize: function () {
var userspanel;
$('ul.tabs').tabs('div.panes > div');
this.contactspanel = new xmppchat.ContactsPanel(); this.contactspanel = new xmppchat.ContactsPanel();
this.roomspanel = new xmppchat.RoomsPanel(); this.roomspanel = new xmppchat.RoomsPanel();
this.settingspanel = new xmppchat.SettingsPanel(); this.settingspanel = new xmppchat.SettingsPanel();
}, },
render: function () { render: function () {
var that = this;
this.$el.hide('fast', function () {
$(this).addClass('chatbox').html(that.template(that.model.toJSON()));
});
return this; return this;
} }
}); });
@ -799,7 +887,8 @@
that = this; that = this;
if (_.indexOf(open_chats, 'controlbox') != -1) { if (_.indexOf(open_chats, 'controlbox') != -1) {
this.createChatBox('controlbox'); // Controlbox already exists, we just need to show it.
this.showChat('controlbox');
} }
_.each(open_chats, $.proxy(function (jid) { _.each(open_chats, $.proxy(function (jid) {
if (jid != 'controlbox') { if (jid != 'controlbox') {
@ -856,6 +945,7 @@
}, },
openChat: function (jid) { openChat: function (jid) {
jid = Strophe.getBareJidFromJid(jid);
if (!this.model.get(jid)) { if (!this.model.get(jid)) {
$.getJSON(portal_url + "/xmpp-userinfo?user_id=" + Strophe.getNodeFromJid(jid), $.proxy(function (data) { $.getJSON(portal_url + "/xmpp-userinfo?user_id=" + Strophe.getNodeFromJid(jid), $.proxy(function (data) {
view = this.createChatBox(jid, data); view = this.createChatBox(jid, data);
@ -903,10 +993,15 @@
initialize: function () { initialize: function () {
this.options.model.on("add", function (item) { this.options.model.on("add", function (item) {
this.showChat(item.get('id')); // The controlbox added automatically, but we don't show it
// automatically (only when it was open before page load or
// upon a click).
if (item.get('id') != 'controlbox') {
this.showChat(item.get('id'));
}
}, this); }, this);
this.views = {}; this.views = {};
this.createChatBox('controlbox');
this.restoreOpenChats(); this.restoreOpenChats();
} }
}); });
@ -919,8 +1014,7 @@
if (!name) { if (!name) {
name = user_id; name = user_id;
} }
this.set({ this.set({ 'id': jid,
'id': jid,
'jid': jid, 'jid': jid,
'ask': ask, 'ask': ask,
'bare_jid': Strophe.getBareJidFromJid(jid), 'bare_jid': Strophe.getBareJidFromJid(jid),
@ -1060,22 +1154,22 @@
rank = 4; rank = 4;
switch(presence_type) { switch(presence_type) {
case 'offline': case 'offline':
rank = 4; rank = 0;
break; break;
case 'unavailable': case 'unavailable':
rank = 3; rank = 1;
break; break;
case 'away': case 'away':
rank = 2; rank = 2;
break; break;
case 'busy': case 'busy':
rank = 1; rank = 3;
break; break;
case 'dnd': case 'dnd':
rank = 1; rank = 4;
break; break;
case 'online': case 'online':
rank = 0; rank = 5;
break; break;
} }
return rank; return rank;
@ -1099,10 +1193,6 @@
return (Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(xmppchat.connection.jid)); return (Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(xmppchat.connection.jid));
}, },
getRoster: function () {
return xmppchat.connection.roster.get($.proxy(this.rosterHandler, this));
},
getItem: function (id) { getItem: function (id) {
return Backbone.Collection.prototype.get.call(this, id); return Backbone.Collection.prototype.get.call(this, id);
}, },
@ -1277,7 +1367,6 @@
} }
return true; return true;
}, },
}); });
xmppchat.RosterView= (function (roster, _, $, console) { xmppchat.RosterView= (function (roster, _, $, console) {
@ -1516,17 +1605,25 @@
this.fullname = chatdata.attr('fullname'); this.fullname = chatdata.attr('fullname');
this.auto_subscribe = chatdata.attr('auto_subscribe') === "True" || false; this.auto_subscribe = chatdata.attr('auto_subscribe') === "True" || false;
$(document).bind('jarnxmpp.connected', $.proxy(function (ev, conn) {
alert("Connection Failed :(");
}, this));
$(document).unbind('jarnxmpp.connected'); $(document).unbind('jarnxmpp.connected');
$(document).bind('jarnxmpp.connected', $.proxy(function () { $(document).bind('jarnxmpp.connected', $.proxy(function () {
// this.connection.xmlInput = function (body) { console.log(body); }; this.connection.xmlInput = function (body) { console.log(body); };
// this.connection.xmlOutput = function (body) { console.log(body); }; this.connection.xmlOutput = function (body) {
console.log(body);
};
this.connection.bare_jid = Strophe.getBareJidFromJid(this.connection.jid); this.connection.bare_jid = Strophe.getBareJidFromJid(this.connection.jid);
this.connection.domain = Strophe.getDomainFromJid(this.connection.jid); this.connection.domain = Strophe.getDomainFromJid(this.connection.jid);
// XXX: Better if configurable?
this.connection.muc_domain = 'conference.' + this.connection.domain; this.connection.muc_domain = 'conference.' + this.connection.domain;
this.storage = new this.ClientStorage({'own_jid': this.connection.bare_jid});
this.storage = new this.ClientStorage(Strophe.getBareJidFromJid(this.connection.jid)); this.chatboxes = new this.ChatBoxes();
this.chatboxesview = new this.ChatBoxesView({
'model': this.chatboxes
});
this.roster = new this.RosterItems(); this.roster = new this.RosterItems();
this.rosterview = Backbone.View.extend(this.RosterView(this.roster, _, $, console)); this.rosterview = Backbone.View.extend(this.RosterView(this.roster, _, $, console));
@ -1534,34 +1631,29 @@
$.proxy(this.roster.subscribeToSuggestedItems, this.roster), $.proxy(this.roster.subscribeToSuggestedItems, this.roster),
'http://jabber.org/protocol/rosterx', 'message', null); 'http://jabber.org/protocol/rosterx', 'message', null);
this.connection.addHandler(
$.proxy(function (presence) {
this.presenceHandler(presence);
return true;
}, this.roster), null, 'presence', null);
this.connection.roster.registerCallback( this.connection.roster.registerCallback(
$.proxy(this.roster.rosterHandler, this.roster), $.proxy(this.roster.rosterHandler, this.roster),
null, 'presence', null); null, 'presence', null);
this.roster.getRoster();
this.chatboxes = new this.ChatBoxes(); this.connection.roster.get($.proxy(function () {
this.chatboxesview = new this.ChatBoxesView({ this.connection.addHandler(
'model': this.chatboxes $.proxy(function (presence) {
}); this.presenceHandler(presence);
return true;
}, this.roster), null, 'presence', null);
this.connection.addHandler( this.connection.addHandler(
$.proxy(function (message) { $.proxy(function (message) {
this.chatboxesview.messageReceived(message); this.chatboxesview.messageReceived(message);
return true; return true;
}, this), null, 'message', 'chat'); }, this), null, 'message', 'chat');
// XMPP Status // XMPP Status
this.xmppstatus = new this.XMPPStatus(); this.xmppstatus = new this.XMPPStatus();
this.xmppstatusview = new this.XMPPStatusView({ this.xmppstatusview = new this.XMPPStatusView({
'model': this.xmppstatus 'model': this.xmppstatus
}); });
}, this));
// Controlbox toggler // Controlbox toggler
$toggle.bind('click', $.proxy(function (e) { $toggle.bind('click', $.proxy(function (e) {