Refactor roster functionality with backbone. (Not done yet).

This commit is contained in:
JC Brand 2012-07-15 13:10:11 +02:00
parent 588ff50aa5
commit 28d71fba34
2 changed files with 199 additions and 97 deletions

232
chat.js
View File

@ -424,7 +424,48 @@ xmppchat.ControlBoxView = xmppchat.ChatBoxView.extend({
el: '#online-users-container', el: '#online-users-container',
events: { events: {
'click a.close-controlbox-button': 'closeChat' 'click a.close-controlbox-button': 'closeChat',
'click div.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(
$('<li></li>')
.attr('id', 'found-users-'+obj.id)
.append(
$('<a class="subscribe-to-user" href="#" title="Click to add as a chat contact"></a>')
.attr('data-recipient', obj.id+'@'+xmppchat.connection.domain)
.text(obj.fullname)
)
);
});
});
},
subscribeToContact: function (ev) {
ev.preventDefault();
var jid = $(ev.target).attr('data-recipient');
xmppchat.roster.stropheRoster.add(jid, '', [], function (iq) {
// XXX: We can set the name here!!!
//xmppchat.connection.send($pres({'type':'result', 'id': $(iq).attr('id')}));
xmppchat.roster.stropheRoster.subscribe(jid);
});
$(ev.target).parent().remove();
$('form.search-xmpp-contact').hide();
}, },
initialize: function () { initialize: function () {
@ -616,7 +657,8 @@ xmppchat.RosterItemView = Backbone.View.extend({
tagName: 'li', tagName: 'li',
events: { events: {
'click': 'openChat' 'click a.open-chat': 'openChat',
'click a.remove-xmpp-contact': 'removeContact'
}, },
openChat: function (e) { openChat: function (e) {
@ -625,6 +667,32 @@ xmppchat.RosterItemView = Backbone.View.extend({
xmppchat.chatboxesview.openChat(jid); xmppchat.chatboxesview.openChat(jid);
}, },
removeContact: function (e) {
var that = this;
e.preventDefault();
$("<span></span>").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: '#online-users-container'
},
modal: true,
buttons: {
"Remove": function() {
$(this).dialog( "close" );
xmppchat.roster.unsubscribe(that.model.get('jid'));
},
"Cancel": function() {
$(this).dialog( "close" );
}
}
});
},
initialize: function () { initialize: function () {
var that = this; var that = this;
this.options.model.on('change', function (item, changed) { this.options.model.on('change', function (item, changed) {
@ -634,9 +702,9 @@ xmppchat.RosterItemView = Backbone.View.extend({
}, this); }, this);
}, },
template: _.template( template: _.template(
'<a title="Click to chat with this contact"><%= fullname %></a>' + '<a class="open-chat" title="Click to chat with this contact" href="#"><%= fullname %></a>' +
'<a title="Click to remove this contact" class="remove-xmpp-contact" href="#"></a>'), '<a class="remove-xmpp-contact" title="Click to remove this contact" href="#"></a>'),
render: function () { render: function () {
var item = this.model; var item = this.model;
@ -654,7 +722,7 @@ xmppchat.Roster = (function (stropheRoster, _, $, console) {
stropheRoster: stropheRoster, stropheRoster: stropheRoster,
initialize: function () { initialize: function () {
this.stropheRoster._connection = xmppchat.connection; this._connection = this.stropheRoster._connection = xmppchat.connection;
}, },
comparator : function (rosteritem) { comparator : function (rosteritem) {
@ -757,48 +825,131 @@ xmppchat.Roster = (function (stropheRoster, _, $, console) {
_.extend(ob, Backbone.Events); _.extend(ob, Backbone.Events);
ob.updateHandler = function (items) { ob.updateHandler = function (items) {
var model; var model, item;
for (var i=0; i<items.length; i++) { for (var i=0; i<items.length; i++) {
if (items[i].subscription === 'none') { item = items[i];
model = ob.getItem(jid);
ob.remove(model); if (item.ask === 'subscribe') {
// We are subscribing to them and have to wait for
// authorization
continue;
}
model = ob.getItem(item.jid);
if (!model) {
if (item.subscription === 'to') {
ob.addRosterItem(item.jid, item.subscription);
}
if (item.subscription === 'both') {
ob.addRosterItem(item.jid, item.subscription);
}
} else { } else {
if (ob.getItem(items[i].jid)) { if (item.subscription === 'none') {
// Update the model ob.remove(model);
model = ob.getItem(jid);
model.subscription = item.subscription;
} else {
ob.addRosterItem(items[i].jid, items[i].subscription);
} }
} }
/*
model = ob.getItem(item.jid);
if (model) {
if (model.get('subscription') === 'both') {
if (item.subscription === 'to') {
// Other user unsubscribed, so we unsubscribe as well.
ob.unsubscribe(item.jid);
} else if (item.subscription === 'from') {
// We have just unsubscribed, remove user.
ob.unauthorize(item.jid);
ob.remove(model);
} else if (item.subscription === 'none') {
if (item.ask === 'subscribe') {
// We already authorized it, so must be something
// wrong.
ob.unauthorize(item.jid);
}
ob.remove(model);
} else {
// Update the model
model = ob.getItem(item.jid);
model.subscription = item.subscription;
}
} else {
if (item.subscription === 'none') {
ob.remove(model);
} else {
// Update the model
model = ob.getItem(item.jid);
model.subscription = item.subscription;
}
}
} else {
if (item.subscription === 'from') {
ob.subscribe(item.jid);
} else if (item.subscription === 'both') {
ob.addRosterItem(item.jid, item.subscription);
} else if (item.subscription === 'to') {
ob.addRosterItem(item.jid, item.subscription);
}
}
*/
} }
}; };
ob.promptUserForSubscription = function (jid, approve_callback, decline_callback) {
var user_id = Strophe.getNodeFromJid(jid);
$("<span></span>").dialog({
title: user_id+ ' wants add you as a contact.',
dialogClass: 'approve-xmpp-contact-dialog',
resizable: false,
width: 200,
position: {
my: 'center',
at: 'center',
of: '#online-users-container'
},
modal: true,
buttons: {
"Approve": function() {
$(this).dialog( "close" );
approve_callback(jid);
},
"Decline": function() {
$(this).dialog( "close" );
decline_callback(jid);
}
}
});
};
ob.presenceHandler = function (presence) { ob.presenceHandler = function (presence) {
var jid = $(presence).attr('from'), var jid = $(presence).attr('from'),
bare_jid = Strophe.getBareJidFromJid(jid), bare_jid = Strophe.getBareJidFromJid(jid),
resource = Strophe.getResourceFromJid(jid), resource = Strophe.getResourceFromJid(jid),
ptype = $(presence).attr('type'), ptype = $(presence).attr('type'),
item,
status = ''; status = '';
if (ob.isSelf(bare_jid)) { if (ob.isSelf(bare_jid)) {
return true; return true;
} }
if (ptype === 'subscribe') { if (ptype === 'subscribe') {
// FIXME: User wants to subscribe to us. Always approve and if (ob.getItem(bare_jid)) {
// ask to subscribe to him xmppchat.roster.authorize(bare_jid);
stropheRoster.authorize(bare_jid); } else {
stropheRoster.subscribe(bare_jid); ob.promptUserForSubscription(bare_jid,
function () { // Approved
} else if (ptype === 'unsubscribe') { xmppchat.roster.authorize(bare_jid);
if (_.indexOf(xmppchat.roster.getCachedJids(), bare_jid) != -1) { xmppchat.roster.subscribe(bare_jid);
stropheRoster.unauthorize(bare_jid); },
stropheRoster.unsubscribe(bare_jid); function () { // Declined
xmppchat.roster.unauthorize(bare_jid);
});
} }
} else if (ptype === 'subscribed') {
return true;
} else if (ptype === 'unsubscribe') {
return true;
} else if (ptype === 'unsubscribed') { } else if (ptype === 'unsubscribed') {
return; return true;
} else if (ptype === 'error') {
return true;
} else if (ptype !== 'error') { // Presence has changed } else if (ptype !== 'error') { // Presence has changed
if (_.indexOf(['unavailable', 'offline', 'busy', 'away'], ptype) != -1) { if (_.indexOf(['unavailable', 'offline', 'busy', 'away'], ptype) != -1) {
@ -827,20 +978,26 @@ xmppchat.RosterView= (function (roster, _, $, console) {
var View = Backbone.View.extend({ var View = Backbone.View.extend({
el: $('#xmpp-contacts'), el: $('#xmpp-contacts'),
model: roster, model: roster,
rosteritemviews: [], rosteritemviews: {},
initialize: function () { initialize: function () {
this.model.on("add", function (item) { this.model.on("add", function (item) {
$(this.el).append((new xmppchat.RosterItemView({model: item})).render().el); var view = new xmppchat.RosterItemView({model: item});
this.rosteritemviews[item.id] = view;
$(this.el).append(view.render().el);
}, this); }, this);
this.model.on('change', function (item) { this.model.on('change', function (item) {
this.render(); this.render();
}, this); }, this);
this.model.on("remove", function (msg) { this.model.on("remove", function (item) {
console.log('roster remove handler called!!!!!'); var view = this.rosteritemviews[item.id];
}); if (view) {
view.remove();
}
this.render();
}, this);
}, },
render: function () { render: function () {
@ -948,6 +1105,15 @@ $(document).ready(function () {
$(document).unbind('jarnxmpp.connected'); $(document).unbind('jarnxmpp.connected');
$(document).bind('jarnxmpp.connected', function () { $(document).bind('jarnxmpp.connected', function () {
xmppchat.connection.xmlInput = function (body) {
console.log(body);
};
xmppchat.connection.xmlOutput = function (body) {
console.log(body);
};
xmppchat.connection.bare_jid = Strophe.getBareJidFromJid(xmppchat.connection.jid); xmppchat.connection.bare_jid = Strophe.getBareJidFromJid(xmppchat.connection.jid);
xmppchat.roster = xmppchat.Roster(Strophe._connectionPlugins.roster, _, $, console); xmppchat.roster = xmppchat.Roster(Strophe._connectionPlugins.roster, _, $, console);

View File

@ -140,72 +140,8 @@ xmppchat.UI = (function (xmppUI, $, console) {
// Event handlers // Event handlers
// -------------- // --------------
$(document).ready(function () { $(document).ready(function () {
$(document).bind('xmppchat.send_presence', function (event, jid, type) {
xmppchat.connection.send($pres({'type':type}));
});
$('ul.tabs').tabs('div.panes > div'); $('ul.tabs').tabs('div.panes > div');
$('div.add-xmpp-contact').click(function (ev) {
ev.preventDefault();
$(this).parent().find('form.search-xmpp-contact').toggle().find('input.username').focus();
});
$('a.remove-xmpp-contact').live('click', function (ev) {
var that = this;
ev.preventDefault();
$("<span></span>").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: '#online-users-container'
},
modal: true,
buttons: {
"Remove": function() {
$( this ).dialog( "close" );
var jid = $(that).parent().attr('data-recipient');
xmppchat.Roster.unsubscribe(jid);
},
"Cancel": function() {
$( this ).dialog( "close" );
}
}
});
});
$('form.search-xmpp-contact').submit(function (ev) {
ev.preventDefault();
$.getJSON(portal_url + "/search-users?q=" + $(this).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(
$('<li></li>')
.attr('id', 'found-users-'+obj.id)
.append(
$('<a class="subscribe-to-user" href="#" title="Click to add as a chat contact"></a>')
.attr('data-recipient', obj.id+'@'+xmppchat.connection.domain)
.text(obj.fullname)
)
);
});
});
});
$("a.subscribe-to-user").live('click', function (ev) {
ev.preventDefault();
xmppchat.Roster.subscribe($(this).attr('data-recipient'));
$(this).remove();
$('form.search-xmpp-contact').hide();
});
$('select#select-xmpp-status').bind('change', function (ev) { $('select#select-xmpp-status').bind('change', function (ev) {
var jid = xmppchat.connection.jid, var jid = xmppchat.connection.jid,
value = ev.target.value; value = ev.target.value;