src/users/UserCollection.js
/** @private */
export const USER_ADDRESS_PREFIX = 'wac-user:';
/** @private */
export const USER_ADDRESS_PATTERN = RegExp(`^(${USER_ADDRESS_PREFIX})(\\w*)$`);
/**
* A local collection of resolved addresses and subscribed addresses.
* @private
*/
export class UserCollection {
/**
* Constructs an users collection
* @param {String} userDomain User's session domain
* @protected
*/
constructor(userDomain) {
/**
* Users indexed by id field.
* @private
* @type {Object}
*/
this._usersById = {};
/**
* Users indexed by complete username (user@domain).
* @private
* @type {Object}
*/
this._usersByCompleteUsername = {};
/**
* Users indexed by alias field.
* @private
* @type {Object}
*/
this._usersByAlias = {};
/**
* Users indexed by landLineNumber field.
* @private
* @type {Object}
*/
this._usersByLandLineNumber = {};
/**
* Users indexed by phone.
* @private
* @type {Object}
*/
this._usersByMobilePhone = {};
/**
* Users indexed by gatewayUsername
* @private
* @type {Object}
*/
this._usersByGatewayUsername = {};
/**
* The user's session domain
* @private
* @type {String}
*/
this._userDomain = userDomain;
/**
* List of requested addresses.
* @private
* @type {Array<String>}
*/
this._subscribed = [];
}
/**
* Check if we are subscribed to an address.
* @param {String} address the address to query.
* @return {Boolean} true if subscribed.
*/
isSubscribedTo(address) {
return this._subscribed.includes(address);
}
/**
* Update the list of subscribed address.
* @param {Array<String>} addresses new subscribed addresses that will
* replace existing one.
*/
updateSubscribed(addresses) {
this._subscribed = addresses;
}
/**
* Add a user to the indexes.
* @protected
* @param {User} user the user to add.
*/
addUser(user) {
user.getAddress = () => {
return USER_ADDRESS_PREFIX + user.id;
};
this._usersById[user.id] = user;
this._usersByCompleteUsername[`${user.username}@${user.domain}`.toLowerCase()] = user;
if (user.alias) {
this._usersByAlias[user.alias] = user;
}
if (user.landLineNumber) {
this._usersByLandLineNumber[user.landLineNumber] = user;
}
if (user.gatewayUsername) {
this._usersByGatewayUsername[user.gatewayUsername] = user;
}
user.mobilePhone.forEach((mobilePhone) => {
this._usersByMobilePhone[mobilePhone] = user;
});
}
/**
* Updates all resolved users and subscribed elements.
* @protected
* @param {Array<User>} users The new resolved users.
* @param {Array<String>} subscribed the new subscribed list.
*/
updateUsers(users, subscribed) {
let newUsers = [];
users.forEach((user) => {
if (this._usersById[user.id]) {
user = Object.assign(this._usersById[user.id], user);
}
newUsers.push(user);
});
this._usersById = {};
this._usersByCompleteUsername = {};
this._usersByAlias = {};
this._usersByLandLineNumber = {};
this._usersByGatewayUsername = {};
this._usersByMobilePhone = {};
this._subscribed = subscribed;
newUsers.forEach(this.addUser.bind(this));
}
/**
* Resolve an address searching in local collection.
* @protected
* @param {String} address the requested address to resolve
* @return {User|undefined} If resolution success, the found User, undefined otherwise.
*/
resolve(address) {
if (USER_ADDRESS_PATTERN.test(address)) {
let id = USER_ADDRESS_PATTERN.exec(address)[2];
return this._usersById[id];
}
return this._usersById[address]
|| this._usersByCompleteUsername[address.toLowerCase()]
|| this._usersByCompleteUsername[`${address}@${this._userDomain}`.toLowerCase()]
|| this._usersByAlias[address]
|| this._usersByLandLineNumber[address]
|| this._usersByMobilePhone[address]
|| this._usersByGatewayUsername[address];
}
}