Commit c8f0fd2a authored by JC Brand's avatar JC Brand

Refactor cleaner separation between converse-vcard and other plugins

parent 64135b77
......@@ -1712,7 +1712,7 @@
'message': msg_text
});
view.model.sendMessage(msg_text);
await u.waitUntil(() => sizzle('.chat-msg .chat-msg__text', chat_content).length === 5);
await u.waitUntil(() => sizzle('.chat-msg .chat-msg__text', chat_content).length === 4, 1000);
msg_txt = sizzle('.chat-msg:last .chat-msg__text', chat_content).pop().textContent;
expect(msg_txt).toEqual(msg_text);
......
......@@ -271,6 +271,7 @@
'jid': 'contact@example.org',
'subscription': 'to',
'name': 'Nicky'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
// Check that the IQ set was acknowledged.
expect(Strophe.serialize(sent_stanza)).toBe( // Strophe adds the xmlns attr (although not in spec)
......
This diff is collapsed.
......@@ -310,7 +310,8 @@ converse.plugins.add('converse-profile', {
/******************** Event Handlers ********************/
_converse.api.listen.on('controlBoxPaneInitialized', (view) => {
_converse.api.listen.on('controlBoxPaneInitialized', async view => {
await _converse.api.waitUntil('statusInitialized');
_converse.xmppstatusview = new _converse.XMPPStatusView({'model': _converse.xmppstatus});
view.el.insertAdjacentElement('afterBegin', _converse.xmppstatusview.render().el);
});
......
......@@ -1288,6 +1288,10 @@ _converse.initialize = async function (settings, callback) {
});
},
getNickname () {
return _converse.nickname;
},
constructPresence (type, status_message) {
let presence;
type = _.isString(type) ? type : (this.get('status') || _converse.default_state);
......
......@@ -222,7 +222,7 @@ converse.plugins.add('converse-muc', {
throw new Error(
"Can't call _converse.getDefaultMUCNickname before the statusInitialized has been fired.");
}
const nick = _converse.nickname || (_converse.vcards ? _converse.xmppstatus.vcard.get('nickname') : undefined);
const nick = _converse.xmppstatus.getNickname();
if (nick) {
return nick;
} else if (_converse.muc_nickname_from_jid) {
......
......@@ -15,7 +15,7 @@ const u = converse.env.utils;
converse.plugins.add('converse-roster', {
dependencies: ["converse-vcard"],
dependencies: [],
initialize () {
/* The initialize function gets called as soon as the plugin is
......@@ -221,30 +221,12 @@ converse.plugins.add('converse-roster', {
});
_converse.ModelWithVCardAndPresence = Backbone.Model.extend({
initialize () {
this.setVCard();
this.setPresence();
},
setVCard () {
if (!_converse.vcards) {
// VCards aren't supported
return;
}
const jid = this.get('jid');
this.vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
},
setPresence () {
const jid = this.get('jid');
this.presence = _converse.presences.findWhere({'jid': jid}) || _converse.presences.create({'jid': jid});
}
});
_converse.RosterContact = _converse.ModelWithVCardAndPresence.extend({
/**
* @class
* @namespace _converse.RosterContact
* @memberOf _converse
*/
_converse.RosterContact = Backbone.Model.extend({
defaults: {
'chat_state': undefined,
'image': _converse.DEFAULT_IMAGE,
......@@ -253,13 +235,10 @@ converse.plugins.add('converse-roster', {
'status': undefined,
},
initialize (attributes) {
_converse.ModelWithVCardAndPresence.prototype.initialize.apply(this, arguments);
const { jid } = attributes,
bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(),
resource = Strophe.getResourceFromJid(jid);
async initialize (attributes) {
this.setPresence();
const { jid } = attributes;
const bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase();
attributes.jid = bare_jid;
this.set(_.assignIn({
'groups': [],
......@@ -276,24 +255,31 @@ converse.plugins.add('converse-roster', {
*/
this.presence.on('change:show', () => _converse.api.trigger('contactPresenceChanged', this));
this.presence.on('change:show', () => this.trigger('presenceChanged'));
/**
* Synchronous event which provides a hook for further initializing a RosterContact
* @event _converse#rosterContactInitialized
* @param { _converse.RosterContact } contact
*/
await _converse.api.trigger('rosterContactInitialized', this, {'Synchronous': true});
},
setPresence () {
const jid = this.get('jid');
this.presence = _converse.presences.findWhere({'jid': jid}) || _converse.presences.create({'jid': jid});
},
getDisplayName () {
// Gets overridden in converse-vcard where the fullname is may be returned
if (this.get('nickname')) {
return this.get('nickname');
} else if (this.vcard) {
return this.vcard.getDisplayName();
} else {
return this.get('jid');
}
},
getFullname () {
if (this.vcard) {
return this.vcard.get('fullname');
} else {
// Gets overridden in converse-vcard where the fullname may be returned
return this.get('jid');
}
},
/**
......@@ -308,7 +294,7 @@ converse.plugins.add('converse-roster', {
if (message && message !== "") {
pres.c("status").t(message).up();
}
const nick = _converse.nickname || _converse.xmppstatus.vcard.get('nickname') || _converse.xmppstatus.vcard.get('fullname');
const nick = _converse.xmppstatus.getNickname();
if (nick) {
pres.c('nick', {'xmlns': Strophe.NS.NICK}).t(nick).up();
}
......@@ -483,11 +469,11 @@ converse.plugins.add('converse-roster', {
},
subscribeToSuggestedItems (msg) {
_.each(msg.querySelectorAll('item'), function (item) {
Array.from(msg.querySelectorAll('item')).forEach(item => {
if (item.getAttribute('action') === 'add') {
_converse.roster.addAndSubscribe(
item.getAttribute('jid'),
_converse.xmppstatus.vcard.get('nickname') || _converse.xmppstatus.vcard.get('fullname')
_converse.xmppstatus.getNickname()
);
}
});
......
......@@ -16,12 +16,46 @@ const u = converse.env.utils;
converse.plugins.add('converse-vcard', {
dependencies: ["converse-roster"],
overrides: {
XMPPStatus: {
getNickname () {
const { _converse } = this.__super__;
const nick = this.__super__.getNickname.apply(this);
if (!nick && _converse.xmppstatus.vcard) {
return _converse.xmppstatus.vcard.get('nickname') || _converse.xmppstatus.vcard.get('fullname');
} else {
return nick;
}
}
},
RosterContact: {
getDisplayName () {
if (!this.get('nickname') && this.vcard) {
return this.vcard.getDisplayName();
} else {
return this.__super__.getDisplayName.apply(this);
}
},
getFullname () {
if (this.vcard) {
return this.vcard.get('fullname');
} else {
return this.__super__.getFullname.apply(this);
}
}
}
},
initialize () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
const { _converse } = this;
_converse.VCard = Backbone.Model.extend({
defaults: {
'image': _converse.DEFAULT_IMAGE,
......@@ -97,14 +131,6 @@ converse.plugins.add('converse-vcard', {
return iq;
}
function setVCard (jid, data) {
if (!jid) {
throw Error("No jid provided for the VCard data");
}
const vcard_el = Strophe.xmlHtmlNode(tpl_vcard(data)).firstElementChild;
return _converse.api.sendIQ(createStanza("set", jid, vcard_el));
}
async function getVCard (_converse, jid) {
const to = Strophe.getBareJidFromJid(jid) === _converse.bare_jid ? null : jid;
let iq;
......@@ -148,6 +174,19 @@ converse.plugins.add('converse-vcard', {
_converse.api.listen.on('addClientFeatures', () => _converse.api.disco.own.features.add(Strophe.NS.VCARD));
function setVCardOnModel (model) {
// TODO: if we can make this method async and wait for the VCard to
// be updated, then we'll avoid unnecessary re-rendering of roster contacts.
const jid = model.get('jid');
model.vcard = _converse.vcards.findWhere({'jid': jid});
if (!model.vcard) {
model.vcard = _converse.vcards.create({'jid': jid});
}
}
_converse.api.listen.on('rosterContactInitialized', contact => setVCardOnModel(contact));
/************************ BEGIN API ************************/
Object.assign(_converse.api, {
/**
......@@ -177,7 +216,11 @@ converse.plugins.add('converse-vcard', {
* }).
*/
set (jid, data) {
return setVCard(jid, data);
if (!jid) {
throw Error("No jid provided for the VCard data");
}
const vcard_el = Strophe.xmlHtmlNode(tpl_vcard(data)).firstElementChild;
return _converse.api.sendIQ(createStanza("set", jid, vcard_el));
},
/**
......@@ -233,12 +276,10 @@ converse.plugins.add('converse-vcard', {
* _converse.api.vcard.update(chatbox);
* });
*/
update (model, force) {
return this.get(model, force)
.then(vcard => {
async update (model, force) {
const vcard = await this.get(model, force);
delete vcard['stanza']
model.save(vcard);
});
}
}
});
......
......@@ -71,7 +71,7 @@
// Names from http://www.fakenamegenerator.com/
mock.req_names = [
'Escalus, Prince of Verona', 'The Nurse', 'Paris'
'Escalus, prince of Verona', 'The Nurse', 'Paris'
];
mock.pend_names = [
'Lord Capulet', 'Lady Capulet', 'Servant'
......
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