Fixed race condition bug. More intelligent fetching of vcards
This commit is contained in:
parent
7a94f73d9f
commit
91bdb56bdb
@ -12,6 +12,11 @@ Changelog
|
||||
[jcbrand]
|
||||
- Fixed alignment of chat messages in Firefox.
|
||||
[jcbrand]
|
||||
- More intelligent fetching of vCards.
|
||||
[jcbrand]
|
||||
- Fixed a race condition bug. Make sure that the roster is populated before
|
||||
sending initial presence.
|
||||
[jcbrand]
|
||||
|
||||
0.3 (2013-05-21)
|
||||
----------------
|
||||
|
126
converse.js
126
converse.js
@ -217,7 +217,7 @@
|
||||
'fullname' : this.get('fullname'),
|
||||
'url': this.get('url'),
|
||||
'image_type': this.get('image_type'),
|
||||
'image_src': this.get('image_src')
|
||||
'image': this.get('image')
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -420,10 +420,7 @@
|
||||
|
||||
keyPressed: function (ev) {
|
||||
var $textarea = $(ev.target),
|
||||
message,
|
||||
notify,
|
||||
composing;
|
||||
|
||||
message, notify, composing;
|
||||
if(ev.keyCode == 13) {
|
||||
ev.preventDefault();
|
||||
message = $textarea.val();
|
||||
@ -436,7 +433,6 @@
|
||||
}
|
||||
}
|
||||
this.$el.data('composing', false);
|
||||
|
||||
} else if (!this.model.get('chatroom')) {
|
||||
// composing data is only for single user chat
|
||||
composing = this.$el.data('composing');
|
||||
@ -470,7 +466,10 @@
|
||||
}
|
||||
} if (_.has(item.changed, 'status')) {
|
||||
this.showStatusMessage(item.get('status'));
|
||||
} if (_.has(item.changed, 'image')) {
|
||||
this.renderAvatar();
|
||||
}
|
||||
// TODO check for changed fullname as well
|
||||
},
|
||||
|
||||
showStatusMessage: function (msg) {
|
||||
@ -485,12 +484,34 @@
|
||||
}
|
||||
},
|
||||
|
||||
updateVCard: function () {
|
||||
var jid = this.model.get('jid'),
|
||||
rosteritem = converse.roster.get(jid);
|
||||
if ((rosteritem)&&(!rosteritem.get('vcard_updated'))) {
|
||||
converse.getVCard(
|
||||
jid,
|
||||
$.proxy(function (jid, fullname, image, image_type, url) {
|
||||
this.model.save({
|
||||
'fullname' : fullname,
|
||||
'url': url,
|
||||
'image_type': image_type,
|
||||
'image': image,
|
||||
'vcard_updated': converse.toISOString(new Date())
|
||||
});
|
||||
}, this),
|
||||
$.proxy(function (stanza) {
|
||||
console.log("ChatBoxView.initialize: An error occured while fetching vcard");
|
||||
}, this)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function (){
|
||||
this.model.messages.on('add', this.showMessage, this);
|
||||
this.model.on('show', this.show, this);
|
||||
this.model.on('destroy', this.hide, this);
|
||||
this.model.on('change', this.onChange, this);
|
||||
|
||||
this.updateVCard();
|
||||
this.$el.appendTo(converse.chatboxesview.$el);
|
||||
this.render().show().model.messages.fetch({add: true});
|
||||
if (this.model.get('status')) {
|
||||
@ -514,10 +535,10 @@
|
||||
'placeholder="Personal message"/>'+
|
||||
'</form>'),
|
||||
|
||||
render: function () {
|
||||
this.$el.attr('id', this.model.get('box_id'))
|
||||
.html(this.template(this.model.toJSON()));
|
||||
if (this.model.get('image')) {
|
||||
renderAvatar: function () {
|
||||
if (!this.model.get('image')) {
|
||||
return;
|
||||
}
|
||||
var img_src = 'data:'+this.model.get('image_type')+';base64,'+this.model.get('image'),
|
||||
canvas = $('<canvas height="35px" width="35px" class="avatar"></canvas>'),
|
||||
ctx = canvas.get(0).getContext('2d'),
|
||||
@ -528,7 +549,12 @@
|
||||
};
|
||||
img.src = img_src;
|
||||
this.$el.find('.chat-title').before(canvas);
|
||||
}
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.attr('id', this.model.get('box_id'))
|
||||
.html(this.template(this.model.toJSON()));
|
||||
this.renderAvatar();
|
||||
return this;
|
||||
},
|
||||
|
||||
@ -584,7 +610,7 @@
|
||||
template: _.template(
|
||||
'<form class="set-xmpp-status" action="" method="post">'+
|
||||
'<span id="xmpp-status-holder">'+
|
||||
'<select id="select-xmpp-status">'+
|
||||
'<select id="select-xmpp-status" style="display:none">'+
|
||||
'<option value="online">Online</option>'+
|
||||
'<option value="dnd">Busy</option>'+
|
||||
'<option value="away">Away</option>'+
|
||||
@ -628,6 +654,7 @@
|
||||
markup = this.add_contact_template();
|
||||
}
|
||||
this.$el.find('.search-xmpp ul').append(markup);
|
||||
this.$el.append(converse.rosterview.$el);
|
||||
return this;
|
||||
},
|
||||
|
||||
@ -1021,6 +1048,22 @@
|
||||
this.contactspanel = new converse.ContactsPanel();
|
||||
this.contactspanel.$parent = this.$el;
|
||||
this.contactspanel.render();
|
||||
converse.xmppstatus = new converse.XMPPStatus();
|
||||
converse.xmppstatus.localStorage = new Backbone.LocalStorage(
|
||||
hex_sha1('converse.xmppstatus-'+converse.bare_jid));
|
||||
converse.xmppstatus.fetch({
|
||||
success: function (xmppstatus, resp) {
|
||||
if (!xmppstatus.get('fullname')) {
|
||||
converse.getVCard(
|
||||
null, // No 'to' attr when getting one's own vCard
|
||||
function (jid, fullname, image, image_type, url) {
|
||||
converse.xmppstatus.save({'fullname': fullname});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
converse.xmppstatusview = new converse.XMPPStatusView({'model': converse.xmppstatus});
|
||||
this.roomspanel = new converse.RoomsPanel();
|
||||
this.roomspanel.$parent = this.$el;
|
||||
this.roomspanel.render();
|
||||
@ -1654,6 +1697,7 @@
|
||||
}
|
||||
this.views[item.get('id')] = view;
|
||||
} else {
|
||||
delete view.model; // Remove ref to old model to help garbage collection
|
||||
view.model = item;
|
||||
view.initialize();
|
||||
if (item.get('id') !== 'controlbox') {
|
||||
@ -1784,6 +1828,16 @@
|
||||
img = $vcard.find('BINVAL').text(),
|
||||
img_type = $vcard.find('TYPE').text(),
|
||||
url = $vcard.find('URL').text();
|
||||
var rosteritem = converse.roster.get(jid);
|
||||
if (rosteritem) {
|
||||
rosteritem.save({
|
||||
'fullname': fullname,
|
||||
'image_type': img_type,
|
||||
'image': img,
|
||||
'url': url,
|
||||
'vcard_updated': converse.toISOString(new Date())
|
||||
});
|
||||
}
|
||||
callback(jid, fullname, img, img_type, url);
|
||||
}, this), jid, errback);
|
||||
}
|
||||
@ -2072,8 +2126,7 @@
|
||||
|
||||
this.$el.hide().html(this.template());
|
||||
this.model.fetch({add: true}); // Get the cached roster items from localstorage
|
||||
this.initialSort();
|
||||
this.$el.appendTo(converse.chatboxesview.views.controlbox.contactspanel.$el);
|
||||
// XXX: is this necessary? this.initialSort();
|
||||
},
|
||||
|
||||
updateChatBox: function (item, changed) {
|
||||
@ -2140,7 +2193,9 @@
|
||||
// options where all of the items are offline and now we can show the rosterView
|
||||
item.set('sorted', true);
|
||||
this.initialSort();
|
||||
this.$el.show();
|
||||
this.$el.show(function () {
|
||||
converse.xmppstatusview.render();
|
||||
});
|
||||
}
|
||||
}
|
||||
// Hide the headings if there are no contacts under them
|
||||
@ -2180,10 +2235,10 @@
|
||||
initStatus: function () {
|
||||
var stat = this.get('status');
|
||||
if (stat === undefined) {
|
||||
this.save({status: 'online'});
|
||||
} else {
|
||||
this.sendPresence(stat);
|
||||
stat = 'online';
|
||||
this.save({status: stat});
|
||||
}
|
||||
this.sendPresence(stat);
|
||||
},
|
||||
|
||||
sendPresence: function (type) {
|
||||
@ -2340,6 +2395,7 @@
|
||||
$options_target = this.$el.find("#target dd ul").hide();
|
||||
$options_target.append(options_list.join(''));
|
||||
$select.remove();
|
||||
this.model.initStatus();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
@ -2537,53 +2593,33 @@
|
||||
this.domain = Strophe.getDomainFromJid(this.connection.jid);
|
||||
this.features = new this.Features();
|
||||
|
||||
|
||||
// Set up the roster
|
||||
this.roster = new this.RosterItems();
|
||||
this.roster.localStorage = new Backbone.LocalStorage(
|
||||
hex_sha1('converse.rosteritems-'+this.bare_jid));
|
||||
|
||||
this.xmppstatus = new this.XMPPStatus({id:1});
|
||||
this.xmppstatus.localStorage = new Backbone.LocalStorage(
|
||||
hex_sha1('converse.xmppstatus-'+this.bare_jid));
|
||||
|
||||
this.chatboxes.onConnected();
|
||||
this.connection.roster.registerCallback(
|
||||
$.proxy(this.roster.rosterHandler, this.roster),
|
||||
null, 'presence', null);
|
||||
this.rosterview = new this.RosterView({'model':this.roster});
|
||||
|
||||
this.xmppstatusview = new this.XMPPStatusView({'model': this.xmppstatus}).render();
|
||||
this.xmppstatus.fetch({
|
||||
success: $.proxy(function (xmppstatus, resp) {
|
||||
if (!xmppstatus.get('fullname')) {
|
||||
this.getVCard(
|
||||
null, // No 'to' attr when getting one's own vCard
|
||||
$.proxy(function (jid, fullname, image, image_type, url) {
|
||||
this.xmppstatus.save({'fullname': fullname});
|
||||
}, this));
|
||||
}
|
||||
}, this)
|
||||
});
|
||||
this.chatboxes.onConnected();
|
||||
|
||||
this.connection.addHandler(
|
||||
$.proxy(this.roster.subscribeToSuggestedItems, this.roster),
|
||||
'http://jabber.org/protocol/rosterx', 'message', null);
|
||||
|
||||
this.connection.roster.registerCallback(
|
||||
$.proxy(this.roster.rosterHandler, this.roster),
|
||||
null, 'presence', null);
|
||||
|
||||
this.connection.roster.get($.proxy(function () {
|
||||
this.connection.roster.get($.proxy(function (a) {
|
||||
this.connection.addHandler(
|
||||
$.proxy(function (presence) {
|
||||
this.presenceHandler(presence);
|
||||
return true;
|
||||
}, this.roster), null, 'presence', null);
|
||||
|
||||
this.connection.addHandler(
|
||||
$.proxy(function (message) {
|
||||
this.chatboxes.messageReceived(message);
|
||||
return true;
|
||||
}, this), null, 'message', 'chat');
|
||||
|
||||
this.xmppstatus.initStatus();
|
||||
}, this));
|
||||
|
||||
$(window).on("blur focus", $.proxy(function(e) {
|
||||
|
2
converse.min.js
vendored
2
converse.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user