Merge pull request #9184 from jitsi/tavram/invite-types
fix(invite) fix notifications for phone invites
This commit is contained in:
commit
6e91665987
|
@ -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)
|
||||
|
|
|
@ -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<P: Props, S: State>
|
|||
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<P: Props, S: State>
|
|||
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<P: Props, S: State>
|
|||
} 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'
|
||||
};
|
||||
|
|
|
@ -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<Props, State> {
|
|||
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<Props, State> {
|
|||
* @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<Props, State> {
|
|||
_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<Props, State> {
|
|||
}
|
||||
|
||||
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));
|
||||
|
|
|
@ -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<Props, State> {
|
|||
* @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<Props, State> {
|
|||
*/
|
||||
_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<Props, State> {
|
|||
content: `${phone} (${name})`,
|
||||
elemBefore: elemAvatar,
|
||||
item: {
|
||||
type: 'phone',
|
||||
type: INVITE_TYPES.PHONE,
|
||||
number: phone
|
||||
},
|
||||
tag: {
|
||||
|
@ -320,7 +321,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
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<Props, State> {
|
|||
});
|
||||
|
||||
|
||||
const sipAddresses = response.filter(item => item.type === 'sip');
|
||||
const sipAddresses = response.filter(item => item.type === INVITE_TYPES.SIP);
|
||||
|
||||
const sipDisplayItems = sipAddresses.map(sip => {
|
||||
return {
|
||||
|
|
|
@ -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'
|
||||
};
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue