diff --git a/react/features/invite/actions.any.js b/react/features/invite/actions.any.js index 893890426..a4424b952 100644 --- a/react/features/invite/actions.any.js +++ b/react/features/invite/actions.any.js @@ -15,6 +15,7 @@ import { UPDATE_DIAL_IN_NUMBERS_FAILED, UPDATE_DIAL_IN_NUMBERS_SUCCESS } from './actionTypes'; +import { INVITE_TYPES } from './constants'; import { getDialInConferenceID, getDialInNumbers, @@ -76,7 +77,7 @@ export function invite( if (showCalleeInfo && !calleeInfoVisible && invitees.length === 1 - && invitees[0].type === 'user' + && invitees[0].type === INVITE_TYPES.USER && participants.length === 1) { dispatch(setCalleeInfoVisible(true, invitees[0])); } @@ -110,7 +111,7 @@ export function invite( // First create all promises for dialing out. const phoneNumbers - = invitesLeftToSend.filter(({ type }) => type === 'phone'); + = invitesLeftToSend.filter(({ type }) => type === INVITE_TYPES.PHONE); // For each number, dial out. On success, remove the number from // {@link invitesLeftToSend}. @@ -131,7 +132,7 @@ export function invite( const usersAndRooms = invitesLeftToSend.filter( - ({ type }) => type === 'user' || type === 'room'); + ({ type }) => [ INVITE_TYPES.USER, INVITE_TYPES.ROOM ].includes(type)); if (usersAndRooms.length) { // Send a request to invite all the rooms and users. On success, @@ -146,7 +147,7 @@ export function invite( .then(() => { invitesLeftToSend = invitesLeftToSend.filter( - ({ type }) => type !== 'user' && type !== 'room'); + ({ type }) => ![ INVITE_TYPES.USER, INVITE_TYPES.ROOM ].includes(type)); }) .catch(error => { dispatch(setCalleeInfoVisible(false)); @@ -159,17 +160,17 @@ export function invite( // Sipgw calls are fire and forget. Invite them to the conference, then // immediately remove them from invitesLeftToSend. const vrooms - = invitesLeftToSend.filter(({ type }) => type === 'videosipgw'); + = invitesLeftToSend.filter(({ type }) => type === INVITE_TYPES.VIDEO_ROOM); conference && vrooms.length > 0 && dispatch(inviteVideoRooms(conference, vrooms)); invitesLeftToSend - = invitesLeftToSend.filter(({ type }) => type !== 'videosipgw'); + = invitesLeftToSend.filter(({ type }) => type !== INVITE_TYPES.VIDEO_ROOM); const sipEndpoints - = invitesLeftToSend.filter(({ type }) => type === 'sip'); + = invitesLeftToSend.filter(({ type }) => type === INVITE_TYPES.SIP); conference && inviteSipEndpoints( sipEndpoints, @@ -182,7 +183,7 @@ export function invite( ); invitesLeftToSend - = invitesLeftToSend.filter(({ type }) => type !== 'sip'); + = invitesLeftToSend.filter(({ type }) => type !== INVITE_TYPES.SIP); return ( Promise.all(allInvitePromises) diff --git a/react/features/invite/components/add-people-dialog/AbstractAddPeopleDialog.js b/react/features/invite/components/add-people-dialog/AbstractAddPeopleDialog.js index 57d0d3da3..79bad8619 100644 --- a/react/features/invite/components/add-people-dialog/AbstractAddPeopleDialog.js +++ b/react/features/invite/components/add-people-dialog/AbstractAddPeopleDialog.js @@ -8,6 +8,7 @@ import { showNotification } from '../../../notifications'; import { invite } from '../../actions'; +import { INVITE_TYPES } from '../../constants'; import { getInviteResultsForQuery, getInviteTypeCounts, @@ -100,6 +101,24 @@ export default class AbstractAddPeopleDialog this._query = this._query.bind(this); } + /** + * Retrieves the notification display name for the invitee. + * + * @param {Object} invitee - The invitee object. + * @returns {string} + */ + _getDisplayName(invitee) { + if (invitee.type === INVITE_TYPES.PHONE) { + return invitee.number; + } + + if (invitee.type === INVITE_TYPES.SIP) { + return invitee.address; + } + + return invitee.name; + } + /** * Invite people and numbers to the conference. The logic works by inviting * numbers, people/rooms, sip endpoints and videosipgw in parallel. All invitees are @@ -160,7 +179,7 @@ export default class AbstractAddPeopleDialog if (invitedCount >= 3) { notificationProps = { titleArguments: { - name: invitees[0].name || invitees[0].address, + name: this._getDisplayName(invitees[0]), count: invitedCount - 1 }, titleKey: 'notify.invitedThreePlusMembers' @@ -168,15 +187,15 @@ export default class AbstractAddPeopleDialog } else if (invitedCount === 2) { notificationProps = { titleArguments: { - first: invitees[0].name || invitees[0].address, - second: invitees[1].name || invitees[1].address + first: this._getDisplayName(invitees[0]), + second: this._getDisplayName(invitees[1]) }, titleKey: 'notify.invitedTwoMembers' }; } else if (invitedCount) { notificationProps = { titleArguments: { - name: invitees[0].name || invitees[0].address + name: this._getDisplayName(invitees[0]) }, titleKey: 'notify.invitedOneMember' }; diff --git a/react/features/invite/components/add-people-dialog/native/AddPeopleDialog.js b/react/features/invite/components/add-people-dialog/native/AddPeopleDialog.js index 7afc2bb9f..c03313d07 100644 --- a/react/features/invite/components/add-people-dialog/native/AddPeopleDialog.js +++ b/react/features/invite/components/add-people-dialog/native/AddPeopleDialog.js @@ -31,7 +31,7 @@ import { } from '../../../../base/react'; import { connect } from '../../../../base/redux'; import { beginShareRoom } from '../../../../share-room'; -import { ADD_PEOPLE_DIALOG_VIEW_ID } from '../../../constants'; +import { ADD_PEOPLE_DIALOG_VIEW_ID, INVITE_TYPES } from '../../../constants'; import AbstractAddPeopleDialog, { type Props as AbstractProps, type State as AbstractState, @@ -242,13 +242,13 @@ class AddPeopleDialog extends AbstractAddPeopleDialog { const { item } = flatListItem; switch (item.type) { - case 'phone': + case INVITE_TYPES.PHONE: return { avatar: IconPhone, key: item.number, title: item.number }; - case 'user': + case INVITE_TYPES.USER: return { avatar: item.avatar, key: item.id || item.user_id, @@ -273,7 +273,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog { * @returns {string} */ _keyExtractor(item) { - return item.type === 'user' ? item.id || item.user_id : item.number; + return item.type === INVITE_TYPES.USER ? item.id || item.user_id : item.number; } _onClearField: () => void @@ -340,7 +340,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog { _onPressItem(item) { return () => { const { inviteItems } = this.state; - const finderKey = item.type === 'phone' ? 'number' : 'user_id'; + const finderKey = item.type === INVITE_TYPES.PHONE ? 'number' : 'user_id'; if (inviteItems.find( _.matchesProperty(finderKey, item[finderKey]))) { @@ -504,10 +504,10 @@ class AddPeopleDialog extends AbstractAddPeopleDialog { } switch (item.type) { - case 'phone': + case INVITE_TYPES.PHONE: selected = inviteItems.find(_.matchesProperty('number', item.number)); break; - case 'user': + case INVITE_TYPES.USER: selected = item.id ? inviteItems.find(_.matchesProperty('id', item.id)) : inviteItems.find(_.matchesProperty('user_id', item.user_id)); diff --git a/react/features/invite/components/add-people-dialog/web/InviteContactsForm.js b/react/features/invite/components/add-people-dialog/web/InviteContactsForm.js index 7b108a23e..0682caa5f 100644 --- a/react/features/invite/components/add-people-dialog/web/InviteContactsForm.js +++ b/react/features/invite/components/add-people-dialog/web/InviteContactsForm.js @@ -12,6 +12,7 @@ import { MultiSelectAutocomplete } from '../../../../base/react'; import { connect } from '../../../../base/redux'; import { isVpaasMeeting } from '../../../../billing-counter/functions'; import { hideAddPeopleDialog } from '../../../actions'; +import { INVITE_TYPES } from '../../../constants'; import AbstractAddPeopleDialog, { type Props as AbstractProps, type State, @@ -181,7 +182,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog { * @returns {Object} The item to display as selected in the input. */ _onItemSelected(item) { - if (item.item.type === 'phone') { + if (item.item.type === INVITE_TYPES.PHONE) { item.content = item.item.number; } @@ -285,7 +286,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog { */ _parseQueryResults(response = []) { const { t, _dialOutEnabled } = this.props; - const users = response.filter(item => item.type !== 'phone' && item.type !== 'sip'); + const users = response.filter(item => item.type === INVITE_TYPES.USER); const userDisplayItems = []; for (const user of users) { @@ -309,7 +310,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog { content: `${phone} (${name})`, elemBefore: elemAvatar, item: { - type: 'phone', + type: INVITE_TYPES.PHONE, number: phone }, tag: { @@ -320,7 +321,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog { } } - const numbers = response.filter(item => item.type === 'phone'); + const numbers = response.filter(item => item.type === INVITE_TYPES.PHONE); const telephoneIcon = this._renderTelephoneIcon(); const numberDisplayItems = numbers.map(number => { @@ -349,7 +350,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog { }); - const sipAddresses = response.filter(item => item.type === 'sip'); + const sipAddresses = response.filter(item => item.type === INVITE_TYPES.SIP); const sipDisplayItems = sipAddresses.map(sip => { return { diff --git a/react/features/invite/constants.js b/react/features/invite/constants.js index b73aeed23..1b8b11e92 100644 --- a/react/features/invite/constants.js +++ b/react/features/invite/constants.js @@ -48,3 +48,14 @@ export const OUTGOING_CALL_START_SOUND_ID = 'OUTGOING_CALL_START_SOUND_ID'; */ // eslint-disable-next-line max-len export const SIP_ADDRESS_REGEX = /^[a-zA-Z]+(?:([^\s>:@]+)(?::([^\s@>]+))?@)?([\w\-.]+)(?::(\d+))?((?:;[^\s=?>;]+(?:=[^\s?;]+)?)*)(?:\?(([^\s&=>]+=[^\s&=>]+)(&[^\s&=>]+=[^\s&=>]+)*))?$/; + +/** + * Different invite types mapping + */ +export const INVITE_TYPES = { + PHONE: 'phone', + ROOM: 'room', + SIP: 'sip', + USER: 'user', + VIDEO_ROOM: 'videosipgw' +}; diff --git a/react/features/invite/functions.js b/react/features/invite/functions.js index b16faee40..2ced54cd5 100644 --- a/react/features/invite/functions.js +++ b/react/features/invite/functions.js @@ -10,7 +10,7 @@ import { toState } from '../base/redux'; import { doGetJSON, parseURIString } from '../base/util'; import { isVpaasMeeting } from '../billing-counter/functions'; -import { SIP_ADDRESS_REGEX } from './constants'; +import { INVITE_TYPES, SIP_ADDRESS_REGEX } from './constants'; import logger from './logger'; declare var $: Function; @@ -227,13 +227,13 @@ export function getInviteResultsForQuery( * the phone number can then be cleaned up when convenient. */ const hasPhoneResult - = peopleResults.find(result => result.type === 'phone'); + = peopleResults.find(result => result.type === INVITE_TYPES.PHONE); if (!hasPhoneResult && typeof phoneResults.allow === 'boolean') { results.push({ allowed: phoneResults.allow, country: phoneResults.country, - type: 'phone', + type: INVITE_TYPES.PHONE, number: phoneResults.phone, originalEntry: text, showCountryCodeReminder: !hasCountryCode @@ -242,7 +242,7 @@ export function getInviteResultsForQuery( if (sipInviteEnabled && isASipAddress(text)) { results.push({ - type: 'sip', + type: INVITE_TYPES.SIP, address: text }); }