Commit 36fd859a authored by JC Brand's avatar JC Brand

Store presence info in a separate collection

So that we can cache roster data for longer and presence data for
shorter.
parent b939de03
...@@ -25,10 +25,13 @@ ...@@ -25,10 +25,13 @@
- #1039 Multi-option data form elements not shown and saved correctly - #1039 Multi-option data form elements not shown and saved correctly
### API changes ### API changes
- `_converse.api.vcard.get` now also accepts a `Backbone.Model` instance and - `_converse.api.vcard.get` now also accepts a `Backbone.Model` instance and
has an additional `force` parameter to force fetching the vcard even if it has an additional `force` parameter to force fetching the vcard even if it
has already been fetched. has already been fetched.
- New API method `_converse.api.vcard.update`. - New API method `_converse.api.vcard.update`.
- The `contactStatusChanged` event has been renamed to `contactPresenceChanged`
and a event `presenceChanged` is now also triggered on the contact.
## UI changes ## UI changes
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
// 'prosody@conference.prosody.im', // 'prosody@conference.prosody.im',
// 'jdev@conference.jabber.org' // 'jdev@conference.jabber.org'
// ], // ],
websocket_url: 'ws://chat.example.org:5280/xmpp-websocket',
view_mode: 'fullscreen', view_mode: 'fullscreen',
archived_messages_page_size: '500', archived_messages_page_size: '500',
allow_public_bookmarks: true, allow_public_bookmarks: true,
...@@ -33,7 +34,7 @@ ...@@ -33,7 +34,7 @@
'discuss@conference.conversejs.org' 'discuss@conference.conversejs.org'
], ],
// bosh_service_url: 'http://chat.example.org:5280/http-bind/', // bosh_service_url: 'http://chat.example.org:5280/http-bind/',
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes // bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
message_archiving: 'always', message_archiving: 'always',
debug: true debug: true
}); });
......
...@@ -179,12 +179,13 @@ The user has removed a contact. ...@@ -179,12 +179,13 @@ The user has removed a contact.
``_converse.api.listen.on('contactRemoved', function (data) { ... });`` ``_converse.api.listen.on('contactRemoved', function (data) { ... });``
contactStatusChanged contactPresenceChanged
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
When a chat buddy's chat status has changed. When a chat buddy's presence status has changed.
The presence status is either `online`, `offline`, `dnd`, `away` or `xa`.
``_converse.api.listen.on('contactStatusChanged', function (buddy) { ... });`` ``_converse.api.listen.on('contactPresenceChanged', function (presence) { ... });``
contactStatusMessageChanged contactStatusMessageChanged
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -1845,7 +1845,7 @@ ...@@ -1845,7 +1845,7 @@
expect(view.model.get('open')).toBe(false); expect(view.model.get('open')).toBe(false);
expect(view.model.get('membersonly')).toBe(true); expect(view.model.get('membersonly')).toBe(true);
done(); done();
}); }).catch(_.partial(console.error, _));
})); }));
it("indicates when a room is no longer anonymous", it("indicates when a room is no longer anonymous",
......
...@@ -134,7 +134,7 @@ ...@@ -134,7 +134,7 @@
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true); spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
spyOn(_converse, 'showChatStateNotification'); spyOn(_converse, 'showChatStateNotification');
var jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost'; var jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'busy'); // This will emit 'contactStatusChanged' _converse.roster.get(jid).presence.set('show', 'busy'); // This will emit 'contactStatusChanged'
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled(); expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
expect(_converse.showChatStateNotification).toHaveBeenCalled(); expect(_converse.showChatStateNotification).toHaveBeenCalled();
})); }));
......
This diff is collapsed.
...@@ -306,7 +306,7 @@ ...@@ -306,7 +306,7 @@
expect($contacts.hasClass('both')).toBeFalsy(); expect($contacts.hasClass('both')).toBeFalsy();
expect($contacts.hasClass('current-xmpp-contact')).toBeTruthy(); expect($contacts.hasClass('current-xmpp-contact')).toBeTruthy();
expect($contacts.text().trim()).toBe('Contact'); expect($contacts.text().trim()).toBe('Contact');
expect(contact.get('chat_status')).toBe('offline'); expect(contact.presence.get('show')).toBe('offline');
/* <presence /* <presence
* from='contact@example.org/resource' * from='contact@example.org/resource'
...@@ -315,7 +315,7 @@ ...@@ -315,7 +315,7 @@
stanza = $pres({'to': _converse.bare_jid, 'from': 'contact@example.org/resource'}); stanza = $pres({'to': _converse.bare_jid, 'from': 'contact@example.org/resource'});
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
// Now the contact should also be online. // Now the contact should also be online.
expect(contact.get('chat_status')).toBe('online'); expect(contact.presence.get('show')).toBe('online');
/* Section 8.3. Creating a Mutual Subscription /* Section 8.3. Creating a Mutual Subscription
* *
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory); define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
} (this, function ($, jasmine, mock, converse, test_utils) { } (this, function ($, jasmine, mock, converse, test_utils) {
var _ = converse.env._; var _ = converse.env._;
var Strophe = converse.env.Strophe;
var $pres = converse.env.$pres; var $pres = converse.env.$pres;
var $msg = converse.env.$msg; var $msg = converse.env.$msg;
var $iq = converse.env.$iq; var $iq = converse.env.$iq;
...@@ -94,16 +95,12 @@ ...@@ -94,16 +95,12 @@
var $roster = $(_converse.rosterview.roster_el); var $roster = $(_converse.rosterview.roster_el);
_converse.rosterview.filter_view.delegateEvents(); _converse.rosterview.filter_view.delegateEvents();
var promise = test_utils.waitUntil(function () { var promise = test_utils.waitUntil(() => $roster.find('li:visible').length === 15, 600)
return $roster.find('li:visible').length === 15; .then(function (contacts) {
}, 600).then(function (contacts) {
expect($roster.find('ul.roster-group-contacts:visible').length).toBe(5); expect($roster.find('ul.roster-group-contacts:visible').length).toBe(5);
$filter[0].value = "candice"; $filter[0].value = "candice";
u.triggerEvent($filter[0], "keydown", "KeyboardEvent"); u.triggerEvent($filter[0], "keydown", "KeyboardEvent");
return test_utils.waitUntil(() => $roster.find('li:visible').length === 1, 600);
return test_utils.waitUntil(function () {
return $roster.find('li:visible').length === 1;
}, 600);
}).then(function (contacts) { }).then(function (contacts) {
// Only one roster contact is now visible // Only one roster contact is now visible
expect($roster.find('li:visible').length).toBe(1); expect($roster.find('li:visible').length).toBe(1);
...@@ -149,7 +146,7 @@ ...@@ -149,7 +146,7 @@
expect($roster.find('ul.roster-group-contacts:visible').length).toBe(5); expect($roster.find('ul.roster-group-contacts:visible').length).toBe(5);
_converse.roster_groups = false; _converse.roster_groups = false;
done(); done();
}); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
})); }));
it("will also filter out contacts added afterwards", it("will also filter out contacts added afterwards",
...@@ -290,26 +287,21 @@ ...@@ -290,26 +287,21 @@
test_utils.createGroupedContacts(_converse); test_utils.createGroupedContacts(_converse);
var jid = mock.cur_names[3].replace(/ /g,'.').toLowerCase() + '@localhost'; var jid = mock.cur_names[3].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'online'); _converse.roster.get(jid).presence.set('show', 'online');
jid = mock.cur_names[4].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[4].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'dnd'); _converse.roster.get(jid).presence.set('show', 'dnd');
test_utils.openControlBox(); test_utils.openControlBox();
var button = _converse.rosterview.el.querySelector('span[data-type="state"]'); var button = _converse.rosterview.el.querySelector('span[data-type="state"]');
button.click(); button.click();
var $roster = $(_converse.rosterview.roster_el); var $roster = $(_converse.rosterview.roster_el);
test_utils.waitUntil(function () { test_utils.waitUntil(() => $roster.find('li:visible').length === 15, 500).then(function () {
return $roster.find('li:visible').length === 15;
}, 500).then(function () {
var filter = _converse.rosterview.el.querySelector('.state-type'); var filter = _converse.rosterview.el.querySelector('.state-type');
expect($roster.find('ul.roster-group-contacts:visible').length).toBe(5); expect($roster.find('ul.roster-group-contacts:visible').length).toBe(5);
filter.value = "online"; filter.value = "online";
u.triggerEvent(filter, 'change'); u.triggerEvent(filter, 'change');
return test_utils.waitUntil(() => $roster.find('li:visible').length === 1, 500);
return test_utils.waitUntil(function () {
return $roster.find('li:visible').length === 1;
}, 500)
}).then(function () { }).then(function () {
expect($roster.find('li:visible').eq(0).text().trim()).toBe('Rinse Sommer'); expect($roster.find('li:visible').eq(0).text().trim()).toBe('Rinse Sommer');
expect($roster.find('ul.roster-group-contacts:visible').length).toBe(1); expect($roster.find('ul.roster-group-contacts:visible').length).toBe(1);
...@@ -323,7 +315,7 @@ ...@@ -323,7 +315,7 @@
}).then(function () { }).then(function () {
expect($roster.find('ul.roster-group-contacts:visible').length).toBe(1); expect($roster.find('ul.roster-group-contacts:visible').length).toBe(1);
done(); done();
}); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
})); }));
}); });
...@@ -851,16 +843,15 @@ ...@@ -851,16 +843,15 @@
function (done, _converse) { function (done, _converse) {
_addContacts(_converse); _addContacts(_converse);
test_utils.waitUntil(function () { test_utils.waitUntil(() => $(_converse.rosterview.el).find('.roster-group li').length, 700)
return $(_converse.rosterview.el).find('.roster-group li').length; .then(function () {
}, 700).then(function () {
var jid, t; var jid, t;
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
spyOn(_converse.rosterview, 'update').and.callThrough(); spyOn(_converse.rosterview, 'update').and.callThrough();
var $roster = $(_converse.rosterview.el); var $roster = $(_converse.rosterview.el);
for (var i=0; i<mock.cur_names.length; i++) { for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'online'); _converse.roster.get(jid).presence.set('show', 'online');
expect(_converse.rosterview.update).toHaveBeenCalled(); expect(_converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically // Check that they are sorted alphabetically
t = _.reduce($roster.find('.roster-group').find('.current-xmpp-contact.online a.open-chat'), function (result, value) { t = _.reduce($roster.find('.roster-group').find('.current-xmpp-contact.online a.open-chat'), function (result, value) {
...@@ -887,7 +878,7 @@ ...@@ -887,7 +878,7 @@
var $roster = $(_converse.rosterview.el); var $roster = $(_converse.rosterview.el);
for (var i=0; i<mock.cur_names.length; i++) { for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'dnd'); _converse.roster.get(jid).presence.set('show', 'dnd');
expect(_converse.rosterview.update).toHaveBeenCalled(); expect(_converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically // Check that they are sorted alphabetically
t = _.reduce($roster.find('.roster-group .current-xmpp-contact.dnd a.open-chat'), t = _.reduce($roster.find('.roster-group .current-xmpp-contact.dnd a.open-chat'),
...@@ -915,7 +906,7 @@ ...@@ -915,7 +906,7 @@
var $roster = $(_converse.rosterview.el); var $roster = $(_converse.rosterview.el);
for (var i=0; i<mock.cur_names.length; i++) { for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'away'); _converse.roster.get(jid).presence.set('show', 'away');
expect(_converse.rosterview.update).toHaveBeenCalled(); expect(_converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically // Check that they are sorted alphabetically
t = _.reduce($roster.find('.roster-group .current-xmpp-contact.away a.open-chat'), t = _.reduce($roster.find('.roster-group .current-xmpp-contact.away a.open-chat'),
...@@ -943,7 +934,7 @@ ...@@ -943,7 +934,7 @@
var $roster = $(_converse.rosterview.el); var $roster = $(_converse.rosterview.el);
for (var i=0; i<mock.cur_names.length; i++) { for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'xa'); _converse.roster.get(jid).presence.set('show', 'xa');
expect(_converse.rosterview.update).toHaveBeenCalled(); expect(_converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically // Check that they are sorted alphabetically
t = _.reduce($roster.find('.roster-group .current-xmpp-contact.xa a.open-chat'), t = _.reduce($roster.find('.roster-group .current-xmpp-contact.xa a.open-chat'),
...@@ -972,7 +963,7 @@ ...@@ -972,7 +963,7 @@
var $roster = $(_converse.rosterview.el); var $roster = $(_converse.rosterview.el);
for (var i=0; i<mock.cur_names.length; i++) { for (var i=0; i<mock.cur_names.length; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'unavailable'); _converse.roster.get(jid).presence.set('show', 'unavailable');
expect(_converse.rosterview.update).toHaveBeenCalled(); expect(_converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically // Check that they are sorted alphabetically
t = _.reduce($roster.find('.roster-group .current-xmpp-contact.unavailable a.open-chat'), t = _.reduce($roster.find('.roster-group .current-xmpp-contact.unavailable a.open-chat'),
...@@ -997,23 +988,23 @@ ...@@ -997,23 +988,23 @@
var i, jid; var i, jid;
for (i=0; i<3; i++) { for (i=0; i<3; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'online'); _converse.roster.get(jid).presence.set('show', 'online');
} }
for (i=3; i<6; i++) { for (i=3; i<6; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'dnd'); _converse.roster.get(jid).presence.set('show', 'dnd');
} }
for (i=6; i<9; i++) { for (i=6; i<9; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'away'); _converse.roster.get(jid).presence.set('show', 'away');
} }
for (i=9; i<12; i++) { for (i=9; i<12; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'xa'); _converse.roster.get(jid).presence.set('show', 'xa');
} }
for (i=12; i<15; i++) { for (i=12; i<15; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost'; jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
_converse.roster.get(jid).set('chat_status', 'unavailable'); _converse.roster.get(jid).presence.set('show', 'unavailable');
} }
return test_utils.waitUntil(function () { return test_utils.waitUntil(function () {
return $(_converse.rosterview.el).find('li.online').length return $(_converse.rosterview.el).find('li.online').length
......
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
var spoiler_hint_el = view.el.querySelector('.spoiler-hint'); var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
expect(spoiler_hint_el.textContent).toBe(''); expect(spoiler_hint_el.textContent).toBe('');
done(); done();
}); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
})); }));
it("can be sent without a hint", it("can be sent without a hint",
...@@ -169,7 +169,7 @@ ...@@ -169,7 +169,7 @@
spoiler_toggle.click(); spoiler_toggle.click();
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy(); expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
done(); done();
}); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
})); }));
it("can be sent with a hint", it("can be sent with a hint",
......
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
}); });
_converse.ChatBox = Backbone.Model.extend({ _converse.ChatBox = _converse.ModelWithVCardAndPresence.extend({
defaults: { defaults: {
'bookmarked': false, 'bookmarked': false,
'chat_state': undefined, 'chat_state': undefined,
...@@ -241,10 +241,8 @@ ...@@ -241,10 +241,8 @@
}, },
initialize () { initialize () {
this.vcard = _converse.vcards.findWhere({'jid': this.get('jid')}); _converse.ModelWithVCardAndPresence.prototype.initialize.apply(this, arguments);
if (_.isNil(this.vcard)) {
this.vcard = _converse.vcards.create({'jid': this.get('jid')});
}
_converse.api.waitUntil('rosterContactsFetched').then(() => { _converse.api.waitUntil('rosterContactsFetched').then(() => {
this.addRelatedContact(_converse.roster.findWhere({'jid': this.get('jid')})); this.addRelatedContact(_converse.roster.findWhere({'jid': this.get('jid')}));
}); });
......
...@@ -344,8 +344,8 @@ ...@@ -344,8 +344,8 @@
this.model.on('show', this.show, this); this.model.on('show', this.show, this);
this.model.on('destroy', this.remove, this); this.model.on('destroy', this.remove, this);
// TODO check for changed fullname as well
this.model.on('change:chat_status', this.onChatStatusChanged, this); this.model.presence.on('change:show', this.onPresenceChanged, this);
this.model.on('showHelpMessages', this.showHelpMessages, this); this.model.on('showHelpMessages', this.showHelpMessages, this);
this.render(); this.render();
...@@ -446,14 +446,14 @@ ...@@ -446,14 +446,14 @@
return; return;
} }
const contact_jid = this.model.get('jid'); const contact_jid = this.model.get('jid');
const resources = this.model.get('resources'); const resources = this.model.presence.get('resources');
if (_.isEmpty(resources)) { if (_.isEmpty(resources)) {
return; return;
} }
Promise.all(_.map(_.keys(resources), (resource) => Promise.all(_.map(_.keys(resources), (resource) =>
_converse.api.disco.supports(Strophe.NS.SPOILER, `${contact_jid}/${resource}`) _converse.api.disco.supports(Strophe.NS.SPOILER, `${contact_jid}/${resource}`)
)).then((results) => { )).then((results) => {
if (results.length) { if (_.filter(results, 'length').length) {
const html = tpl_spoiler_button(this.model.toJSON()); const html = tpl_spoiler_button(this.model.toJSON());
if (_converse.visible_toolbar_buttons.emoji) { if (_converse.visible_toolbar_buttons.emoji) {
this.el.querySelector('.toggle-smiley').insertAdjacentHTML('afterEnd', html); this.el.querySelector('.toggle-smiley').insertAdjacentHTML('afterEnd', html);
...@@ -999,20 +999,19 @@ ...@@ -999,20 +999,19 @@
} }
}, },
onChatStatusChanged (item) { onPresenceChanged (item) {
const chat_status = item.get('chat_status'); const show = item.get('show'),
let fullname = item.get('fullname'); fullname = this.model.getDisplayName();
let text;
fullname = _.isEmpty(fullname)? item.get('jid'): fullname; let text;
if (u.isVisible(this.el)) { if (u.isVisible(this.el)) {
if (chat_status === 'offline') { if (show === 'offline') {
text = fullname+' '+__('has gone offline'); text = fullname+' '+__('has gone offline');
} else if (chat_status === 'away') { } else if (show === 'away') {
text = fullname+' '+__('has gone away'); text = fullname+' '+__('has gone away');
} else if ((chat_status === 'dnd')) { } else if ((show === 'dnd')) {
text = fullname+' '+__('is busy'); text = fullname+' '+__('is busy');
} else if (chat_status === 'online') { } else if (show === 'online') {
text = fullname+' '+__('is online'); text = fullname+' '+__('is online');
} }
if (text) { if (text) {
......
...@@ -751,13 +751,6 @@ ...@@ -751,13 +751,6 @@
}; };
this.unregisterPresenceHandler = function () {
if (!_.isUndefined(_converse.presence_ref)) {
_converse.connection.deleteHandler(_converse.presence_ref);
delete _converse.presence_ref;
}
};
this.sendInitialPresence = function () { this.sendInitialPresence = function () {
if (_converse.send_initial_presence) { if (_converse.send_initial_presence) {
_converse.xmppstatus.sendPresence(); _converse.xmppstatus.sendPresence();
...@@ -1094,7 +1087,6 @@ ...@@ -1094,7 +1087,6 @@
* connection. * connection.
*/ */
_converse.emit('beforeTearDown'); _converse.emit('beforeTearDown');
_converse.unregisterPresenceHandler();
if (!_.isUndefined(_converse.session)) { if (!_.isUndefined(_converse.session)) {
_converse.session.destroy(); _converse.session.destroy();
} }
......
...@@ -448,8 +448,8 @@ ...@@ -448,8 +448,8 @@
if (_.isNil(entity_jid)) { if (_.isNil(entity_jid)) {
throw new TypeError('disco.supports: You need to provide an entity JID'); throw new TypeError('disco.supports: You need to provide an entity JID');
} }
return _converse.api.waitUntil('discoInitialized').then(() => { return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => { return _converse.api.waitUntil('discoInitialized').then(() => {
_converse.api.disco.entities.get(entity_jid, true).then((entity) => { _converse.api.disco.entities.get(entity_jid, true).then((entity) => {
entity.waitUntilFeaturesDiscovered.then(() => { entity.waitUntilFeaturesDiscovered.then(() => {
const promises = _.concat( const promises = _.concat(
...@@ -460,8 +460,8 @@ ...@@ -460,8 +460,8 @@
resolve(f.filter(f.isObject, result)); resolve(f.filter(f.isObject, result));
}).catch(reject); }).catch(reject);
}).catch(reject); }).catch(reject);
}) }).catch(reject);
}); }).catch(reject);
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}, },
......
...@@ -225,7 +225,7 @@ ...@@ -225,7 +225,7 @@
}; };
_converse.handleChatStateNotification = function (contact) { _converse.handleChatStateNotification = function (contact) {
/* Event handler for on('contactStatusChanged'). /* Event handler for on('contactPresenceChanged').
* Will show an HTML5 notification to indicate that the chat * Will show an HTML5 notification to indicate that the chat
* status has changed. * status has changed.
*/ */
...@@ -274,7 +274,7 @@ ...@@ -274,7 +274,7 @@
// registered, because other plugins might override some of our // registered, because other plugins might override some of our
// handlers. // handlers.
_converse.on('contactRequest', _converse.handleContactRequestNotification); _converse.on('contactRequest', _converse.handleContactRequestNotification);
_converse.on('contactStatusChanged', _converse.handleChatStateNotification); _converse.on('contactPresenceChanged', _converse.handleChatStateNotification);
_converse.on('message', _converse.handleMessageNotification); _converse.on('message', _converse.handleMessageNotification);
_converse.on('feedback', _converse.handleFeedback); _converse.on('feedback', _converse.handleFeedback);
_converse.on('connected', _converse.requestPermission); _converse.on('connected', _converse.requestPermission);
......
This diff is collapsed.
...@@ -371,6 +371,8 @@ ...@@ -371,6 +371,8 @@
this.model.on("destroy", this.remove, this); this.model.on("destroy", this.remove, this);
this.model.on("open", this.openChat, this); this.model.on("open", this.openChat, this);
this.model.on("remove", this.remove, this); this.model.on("remove", this.remove, this);
this.model.presence.on("change:show", this.render, this);
this.model.vcard.on('change:fullname', this.render, this); this.model.vcard.on('change:fullname', this.render, this);
}, },
...@@ -382,7 +384,7 @@ ...@@ -382,7 +384,7 @@
} }
const item = this.model, const item = this.model,
ask = item.get('ask'), ask = item.get('ask'),
chat_status = item.get('chat_status'), show = item.presence.get('show'),
requesting = item.get('requesting'), requesting = item.get('requesting'),
subscription = item.get('subscription'); subscription = item.get('subscription');
...@@ -398,8 +400,8 @@ ...@@ -398,8 +400,8 @@
that.el.classList.remove(cls); that.el.classList.remove(cls);
} }
}); });
this.el.classList.add(chat_status); this.el.classList.add(show);
this.el.setAttribute('data-status', chat_status); this.el.setAttribute('data-status', show);
if ((ask === 'subscribe') || (subscription === 'from')) { if ((ask === 'subscribe') || (subscription === 'from')) {
/* ask === 'subscribe' /* ask === 'subscribe'
...@@ -444,21 +446,21 @@ ...@@ -444,21 +446,21 @@
renderRosterItem (item) { renderRosterItem (item) {
let status_icon = 'fa-times-circle'; let status_icon = 'fa-times-circle';
const chat_status = item.get('chat_status') || 'offline'; const show = item.presence.get('show') || 'offline';
if (chat_status === 'online') { if (show === 'online') {
status_icon = 'fa-circle'; status_icon = 'fa-circle';
} else if (chat_status === 'away') { } else if (show === 'away') {
status_icon = 'fa-dot-circle-o'; status_icon = 'fa-dot-circle-o';
} else if (chat_status === 'xa') { } else if (show === 'xa') {
status_icon = 'fa-circle-o'; status_icon = 'fa-circle-o';
} else if (chat_status === 'dnd') { } else if (show === 'dnd') {
status_icon = 'fa-minus-circle'; status_icon = 'fa-minus-circle';
} }
const display_name = item.getDisplayName(); const display_name = item.getDisplayName();
this.el.innerHTML = tpl_roster_item( this.el.innerHTML = tpl_roster_item(
_.extend(item.toJSON(), { _.extend(item.toJSON(), {
'display_name': display_name, 'display_name': display_name,
'desc_status': STATUSES[chat_status], 'desc_status': STATUSES[show],
'status_icon': status_icon, 'status_icon': status_icon,
'desc_chat': __('Click to chat with %1$s (JID: %2$s)', display_name, item.get('jid')), 'desc_chat': __('Click to chat with %1$s (JID: %2$s)', display_name, item.get('jid')),
'desc_remove': __('Click to remove %1$s as a contact', display_name), 'desc_remove': __('Click to remove %1$s as a contact', display_name),
...@@ -476,7 +478,7 @@ ...@@ -476,7 +478,7 @@
* It doesn't check for the more specific case of whether * It doesn't check for the more specific case of whether
* the group it's in is collapsed. * the group it's in is collapsed.
*/ */
const chatStatus = this.model.get('chat_status'); const chatStatus = this.model.presence.get('show');
if ((_converse.show_only_online_users && chatStatus !== 'online') || if ((_converse.show_only_online_users && chatStatus !== 'online') ||
(_converse.hide_offline_users && chatStatus === 'offline')) { (_converse.hide_offline_users && chatStatus === 'offline')) {
// If pending or requesting, show // If pending or requesting, show
...@@ -544,7 +546,7 @@ ...@@ -544,7 +546,7 @@
ItemView: _converse.RosterContactView, ItemView: _converse.RosterContactView,
listItems: 'model.contacts', listItems: 'model.contacts',
listSelector: '.roster-group-contacts', listSelector: '.roster-group-contacts',
sortEvent: 'change:chat_status', sortEvent: 'presenceChanged',
initialize () { initialize () {
Backbone.OrderedListView.prototype.initialize.apply(this, arguments); Backbone.OrderedListView.prototype.initialize.apply(this, arguments);
...@@ -629,13 +631,13 @@ ...@@ -629,13 +631,13 @@
// show requesting contacts, even though they don't // show requesting contacts, even though they don't
// have the state in question. // have the state in question.
matches = this.model.contacts.filter( matches = this.model.contacts.filter(
(contact) => u.contains.not('chat_status', q)(contact) && !contact.get('requesting') (contact) => !_.includes(contact.presence.get('show'), q) && !contact.get('requesting')
); );
} else if (q === 'unread_messages') { } else if (q === 'unread_messages') {
matches = this.model.contacts.filter({'num_unread': 0}); matches = this.model.contacts.filter({'num_unread': 0});
} else { } else {
matches = this.model.contacts.filter( matches = this.model.contacts.filter(
u.contains.not('chat_status', q) (contact) => !_.includes(contact.presence.get('show'), q)
); );
} }
} else { } else {
...@@ -745,6 +747,10 @@ ...@@ -745,6 +747,10 @@
_converse.roster.on('change', this.onContactChange, this); _converse.roster.on('change', this.onContactChange, this);
_converse.roster.on("destroy", this.update, this); _converse.roster.on("destroy", this.update, this);
_converse.roster.on("remove", this.update, this); _converse.roster.on("remove", this.update, this);
_converse.presences.on('change:show', () => {
this.update();
this.updateFilter();
});
this.model.on("reset", this.reset, this); this.model.on("reset", this.reset, this);
...@@ -848,12 +854,14 @@ ...@@ -848,12 +854,14 @@
}, },
onContactAdded (contact) { onContactAdded (contact) {
this.addRosterContact(contact).update(); this.addRosterContact(contact)
this.update();
this.updateFilter(); this.updateFilter();
}, },
onContactChange (contact) { onContactChange (contact) {
this.updateChatBox(contact).update(); this.updateChatBox(contact)
this.update();
if (_.has(contact.changed, 'subscription')) { if (_.has(contact.changed, 'subscription')) {
if (contact.changed.subscription === 'from') { if (contact.changed.subscription === 'from') {
this.addContactToGroup(contact, HEADER_PENDING_CONTACTS); this.addContactToGroup(contact, HEADER_PENDING_CONTACTS);
...@@ -876,9 +884,6 @@ ...@@ -876,9 +884,6 @@
if (!chatbox) { if (!chatbox) {
return this; return this;
} }
if (_.has(contact.changed, 'chat_status')) {
changes.chat_status = contact.get('chat_status');
}
if (_.has(contact.changed, 'status')) { if (_.has(contact.changed, 'status')) {
changes.status = contact.get('status'); changes.status = contact.get('status');
} }
......
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
/* Event handlers */ /* Event handlers */
_converse.initVCardCollection = function () { _converse.initVCardCollection = function () {
_converse.vcards = new _converse.VCards(); _converse.vcards = new _converse.VCards();
_converse.vcards.browserStorage = new Backbone.BrowserStorage.local(b64_sha1(`converse.vcards`)); _converse.vcards.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1(`converse.vcards`));
_converse.vcards.fetch(); _converse.vcards.fetch();
} }
_converse.api.listen.on('connectionInitialized', _converse.initVCardCollection); _converse.api.listen.on('connectionInitialized', _converse.initVCardCollection);
......
<div class="col col-9"> <div class="col col-8">
<div class="chat-title" title="{{{o.jid}}}"> <div class="chat-title" title="{{{o.jid}}}">
{[ if (o.name && o.name !== o.Strophe.getNodeFromJid(o.jid)) { ]} {[ if (o.name && o.name !== o.Strophe.getNodeFromJid(o.jid)) { ]}
{{{ o.name }}} {{{ o.name }}}
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
stanza.c('item', {'jid': item}).up(); stanza.c('item', {'jid': item}).up();
}); });
_converse.connection._dataRecv(utils.createRequest(stanza)); _converse.connection._dataRecv(utils.createRequest(stanza));
}); }).catch(_.partial(console.error, _));
} }
utils.createRequest = function (iq) { utils.createRequest = function (iq) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment