Make sure that the occupant_id
is also the id
for occupants
insofar we have an `occupant_id`. We do this by subclassing `create` on the `ChatRoomOccupants` collection and `save` on the `ChatRoomOccupant` model, to make sure that whenever an occupant is created or saved, that the `id` matches the `occupant_id` value if it's available. This lets us look up the occupant via `occupant_id` via dictionary lookup, instead of array traversal. Another change is to save `from_real_jid` when adding an occupant to a message
This commit is contained in:
parent
b71a7ae2ac
commit
d22c063ae5
@ -81,13 +81,14 @@ const ChatRoomMessageMixin = {
|
|||||||
} else if (occupant.get('nick') !== Strophe.getResourceFromJid(this.get('from'))) {
|
} else if (occupant.get('nick') !== Strophe.getResourceFromJid(this.get('from'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.occupant = occupant;
|
|
||||||
this.trigger('occupantAdded');
|
|
||||||
this.listenTo(this.occupant, 'destroy', this.onOccupantRemoved);
|
|
||||||
const chatbox = this?.collection?.chatbox;
|
const chatbox = this?.collection?.chatbox;
|
||||||
if (!chatbox) {
|
if (!chatbox) {
|
||||||
return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`);
|
return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.occupant = occupant;
|
||||||
|
this.trigger('occupantAdded');
|
||||||
|
this.listenTo(this.occupant, 'destroy', this.onOccupantRemoved);
|
||||||
this.stopListening(chatbox.occupants, 'add', this.onOccupantAdded);
|
this.stopListening(chatbox.occupants, 'add', this.onOccupantAdded);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -100,10 +101,11 @@ const ChatRoomMessageMixin = {
|
|||||||
return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`);
|
return log.error(`Could not get collection.chatbox for message: ${JSON.stringify(this.toJSON())}`);
|
||||||
}
|
}
|
||||||
const nick = Strophe.getResourceFromJid(this.get('from'));
|
const nick = Strophe.getResourceFromJid(this.get('from'));
|
||||||
this.occupant = chatbox.occupants.findOccupant({ nick, 'occupant_id': this.get('occupant_id') });
|
const occupant_id = this.get('occupant_id');
|
||||||
|
this.occupant = chatbox.occupants.findOccupant({ nick, occupant_id });
|
||||||
|
|
||||||
if (!this.occupant && api.settings.get('muc_send_probes')) {
|
if (!this.occupant && api.settings.get('muc_send_probes')) {
|
||||||
this.occupant = chatbox.occupants.create({ nick, 'type': 'unavailable' });
|
this.occupant = chatbox.occupants.create({ nick, occupant_id, 'type': 'unavailable' });
|
||||||
const jid = `${chatbox.get('jid')}/${nick}`;
|
const jid = `${chatbox.get('jid')}/${nick}`;
|
||||||
api.user.presence.send('probe', jid);
|
api.user.presence.send('probe', jid);
|
||||||
}
|
}
|
||||||
|
@ -1704,6 +1704,7 @@ const ChatRoomMixin = {
|
|||||||
if (data.type === 'error' || (!data.jid && !data.nick && !data.occupant_id)) {
|
if (data.type === 'error' || (!data.jid && !data.nick && !data.occupant_id)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const occupant = this.occupants.findOccupant(data);
|
const occupant = this.occupants.findOccupant(data);
|
||||||
// Destroy an unavailable occupant if this isn't a nick change operation and if they're not affiliated
|
// Destroy an unavailable occupant if this isn't a nick change operation and if they're not affiliated
|
||||||
if (
|
if (
|
||||||
@ -1717,11 +1718,14 @@ const ChatRoomMixin = {
|
|||||||
occupant.destroy();
|
occupant.destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const jid = data.jid || '';
|
const jid = data.jid || '';
|
||||||
const attributes = Object.assign(data, {
|
const attributes = {
|
||||||
|
...data,
|
||||||
'jid': Strophe.getBareJidFromJid(jid) || occupant?.attributes?.jid,
|
'jid': Strophe.getBareJidFromJid(jid) || occupant?.attributes?.jid,
|
||||||
'resource': Strophe.getResourceFromJid(jid) || occupant?.attributes?.resource
|
'resource': Strophe.getResourceFromJid(jid) || occupant?.attributes?.resource
|
||||||
});
|
}
|
||||||
|
|
||||||
if (occupant) {
|
if (occupant) {
|
||||||
occupant.save(attributes);
|
occupant.save(attributes);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,10 +2,12 @@ import ChatRoomOccupant from './occupant.js';
|
|||||||
import u from '../../utils/form';
|
import u from '../../utils/form';
|
||||||
import { Collection } from '@converse/skeletor/src/collection.js';
|
import { Collection } from '@converse/skeletor/src/collection.js';
|
||||||
import { MUC_ROLE_WEIGHTS } from './constants.js';
|
import { MUC_ROLE_WEIGHTS } from './constants.js';
|
||||||
|
import { Model } from '@converse/skeletor/src/model.js';
|
||||||
import { Strophe } from 'strophe.js/src/strophe.js';
|
import { Strophe } from 'strophe.js/src/strophe.js';
|
||||||
import { _converse, api } from '../../core.js';
|
import { _converse, api } from '../../core.js';
|
||||||
import { getAffiliationList } from './affiliations/utils.js';
|
import { getAffiliationList } from './affiliations/utils.js';
|
||||||
import { getAutoFetchedAffiliationLists } from './utils.js';
|
import { getAutoFetchedAffiliationLists } from './utils.js';
|
||||||
|
import { getUniqueId } from '@converse/headless/utils/core.js';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +31,14 @@ class ChatRoomOccupants extends Collection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create (attrs, options) {
|
||||||
|
if (attrs.id || attrs instanceof Model) {
|
||||||
|
return super.create(attrs, options);
|
||||||
|
}
|
||||||
|
attrs.id = attrs.occupant_id || getUniqueId();
|
||||||
|
return super.create(attrs, options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link _converse.ChatRoomOccupant} instance which
|
* Get the {@link _converse.ChatRoomOccupant} instance which
|
||||||
* represents the current user.
|
* represents the current user.
|
||||||
@ -94,16 +104,23 @@ class ChatRoomOccupants extends Collection {
|
|||||||
* Try to find an existing occupant based on the passed in
|
* Try to find an existing occupant based on the passed in
|
||||||
* data object.
|
* data object.
|
||||||
*
|
*
|
||||||
* If we have a JID, we use that as lookup variable,
|
* Fetching the user by occupant_id is the quickest, O(1),
|
||||||
* otherwise we use the nick. We don't always have both,
|
* since it's a dictionary lookup.
|
||||||
* but should have at least one or the other.
|
*
|
||||||
|
* Fetching by jid or nick is O(n), since it requires traversing an array.
|
||||||
|
*
|
||||||
|
* Lookup by occupant_id is done first, then jid, and then nick.
|
||||||
|
*
|
||||||
* @method _converse.ChatRoomOccupants#findOccupant
|
* @method _converse.ChatRoomOccupants#findOccupant
|
||||||
* @param { OccupantData } data
|
* @param { OccupantData } data
|
||||||
*/
|
*/
|
||||||
findOccupant (data) {
|
findOccupant (data) {
|
||||||
|
if (data.occupant_id && this.get(data.occupant_id)) {
|
||||||
|
return this.get(data.occupant_id);
|
||||||
|
}
|
||||||
|
|
||||||
const jid = data.jid && Strophe.getBareJidFromJid(data.jid);
|
const jid = data.jid && Strophe.getBareJidFromJid(data.jid);
|
||||||
return jid && this.findWhere({ jid }) ||
|
return jid && this.findWhere({ jid }) ||
|
||||||
data.occupant_id && this.findWhere({ 'occupant_id': data.occupant_id }) ||
|
|
||||||
data.nick && this.findWhere({ 'nick': data.nick });
|
data.nick && this.findWhere({ 'nick': data.nick });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user