(feature) - Add support for custom DID numbers page url

This commit is contained in:
horymury 2021-02-24 11:37:14 +02:00 committed by GitHub
parent d22792c9e3
commit 79bb98dab3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 101 additions and 143 deletions

View File

@ -58,6 +58,14 @@ const DEFAULT_STATE = {
*/
defaultBranding: true,
/**
* Url for a custom page for DID numbers list.
*
* @public
* @type {string}
*/
didPageUrl: '',
/**
* The custom invite domain.
*
@ -101,6 +109,7 @@ ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
backgroundColor,
backgroundImageUrl,
defaultBranding,
didPageUrl,
inviteDomain,
logoClickUrl,
logoImageUrl
@ -110,6 +119,7 @@ ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
backgroundColor,
backgroundImageUrl,
defaultBranding,
didPageUrl,
inviteDomain,
logoClickUrl,
logoImageUrl,

View File

@ -1,14 +1,12 @@
// @flow
import React, { useState, useEffect } from 'react';
import React, { useEffect } from 'react';
import { createInviteDialogEvent, sendAnalytics } from '../../../../analytics';
import { getRoomName } from '../../../../base/conference';
import { getInviteURL } from '../../../../base/connection';
import { Dialog } from '../../../../base/dialog';
import { translate } from '../../../../base/i18n';
import { JitsiRecordingConstants } from '../../../../base/lib-jitsi-meet';
import { getLocalParticipant } from '../../../../base/participants';
import { connect } from '../../../../base/redux';
import { isVpaasMeeting } from '../../../../billing-counter/functions';
import EmbedMeetingTrigger from '../../../../embed-meeting/components/EmbedMeetingTrigger';
@ -26,11 +24,6 @@ declare var interfaceConfig: Object;
type Props = {
/**
* The name of the current conference. Used as part of inviting users.
*/
_conferenceName: string,
/**
* The object representing the dialIn feature.
*/
@ -41,6 +34,11 @@ type Props = {
*/
_embedMeetingVisible: boolean,
/**
* The meeting invitation text.
*/
_invitationText: string,
/**
* Whether or not invite contacts should be visible.
*/
@ -57,14 +55,9 @@ type Props = {
_liveStreamViewURL: string,
/**
* The redux representation of the local participant.
* The default phone number.
*/
_localParticipantName: ?string,
/**
* The current location url of the conference.
*/
_locationUrl: Object,
_phoneNumber: ?string,
/**
* Invoked to obtain translated strings.
@ -83,17 +76,15 @@ type Props = {
* @returns {React$Element<any>}
*/
function AddPeopleDialog({
_conferenceName,
_dialIn,
_embedMeetingVisible,
_invitationText,
_inviteContactsVisible,
_inviteUrl,
_liveStreamViewURL,
_localParticipantName,
_locationUrl,
_phoneNumber,
t,
updateNumbers }: Props) {
const [ phoneNumber, setPhoneNumber ] = useState(undefined);
/**
* Updates the dial-in numbers.
@ -119,27 +110,6 @@ function AddPeopleDialog({
};
}, []);
/**
* Updates the phone number in the state once the dial-in numbers are fetched.
*
* @returns {void}
*/
useEffect(() => {
if (!phoneNumber && _dialIn && _dialIn.numbers) {
setPhoneNumber(_getDefaultPhoneNumber(_dialIn.numbers));
}
}, [ _dialIn ]);
const invite = getInviteText({
_conferenceName,
_localParticipantName,
_inviteUrl,
_locationUrl,
_dialIn,
_liveStreamViewURL,
phoneNumber,
t
});
const inviteSubject = t('addPeople.inviteMoreMailSubject', {
appName: interfaceConfig.APP_NAME
});
@ -156,7 +126,7 @@ function AddPeopleDialog({
<CopyMeetingLinkSection url = { _inviteUrl } />
<InviteByEmailSection
inviteSubject = { inviteSubject }
inviteText = { invite } />
inviteText = { _invitationText } />
{ _embedMeetingVisible && <EmbedMeetingTrigger /> }
<div className = 'invite-more-dialog separator' />
{
@ -165,11 +135,7 @@ function AddPeopleDialog({
}
{
_dialIn.numbers
&& <DialInSection
conferenceName = { _conferenceName }
dialIn = { _dialIn }
locationUrl = { _locationUrl }
phoneNumber = { phoneNumber } />
&& <DialInSection phoneNumber = { _phoneNumber } />
}
</div>
</Dialog>
@ -181,29 +147,32 @@ function AddPeopleDialog({
* {@code AddPeopleDialog} component.
*
* @param {Object} state - The Redux state.
* @param {Object} ownProps - The properties explicitly passed to the component.
* @private
* @returns {Props}
*/
function mapStateToProps(state) {
const localParticipant = getLocalParticipant(state);
function mapStateToProps(state, ownProps) {
const currentLiveStreamingSession
= getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
const { iAmRecorder } = state['features/base/config'];
const addPeopleEnabled = isAddPeopleEnabled(state);
const dialOutEnabled = isDialOutEnabled(state);
const hideInviteContacts = iAmRecorder || (!addPeopleEnabled && !dialOutEnabled);
const dialIn = state['features/invite'];
const phoneNumber = dialIn && dialIn.numbers ? _getDefaultPhoneNumber(dialIn.numbers) : undefined;
return {
_conferenceName: getRoomName(state),
_dialIn: state['features/invite'],
_dialIn: dialIn,
_embedMeetingVisible: !isVpaasMeeting(state),
_invitationText: getInviteText({ state,
phoneNumber,
t: ownProps.t }),
_inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts,
_inviteUrl: getInviteURL(state),
_liveStreamViewURL:
currentLiveStreamingSession
&& currentLiveStreamingSession.liveStreamViewURL,
_localParticipantName: localParticipant?.name,
_locationUrl: state['features/base/connection'].locationURL
_phoneNumber: phoneNumber
};
}

View File

@ -3,26 +3,22 @@
import React from 'react';
import { translate } from '../../../../base/i18n';
import { connect } from '../../../../base/redux';
import { getDialInfoPageURL } from '../../../functions';
import DialInNumber from './DialInNumber';
type Props = {
/**
* The name of the current conference. Used as part of inviting users.
*/
conferenceName: string,
/**
* The object representing the dialIn feature.
*/
dialIn: Object,
_dialIn: Object,
/**
* The current location url of the conference.
* The url of the page containing the dial-in numbers list.
*/
locationUrl: Object,
_dialInfoPageUrl: string,
/**
* The phone number to dial to begin the process of dialing into a
@ -45,25 +41,19 @@ type Props = {
* @returns {null|ReactElement}
*/
function DialInSection({
conferenceName,
dialIn,
locationUrl,
_dialIn,
_dialInfoPageUrl,
phoneNumber,
t
}: Props) {
return (
<div className = 'invite-more-dialog dial-in-display'>
<DialInNumber
conferenceID = { dialIn.conferenceID }
conferenceID = { _dialIn.conferenceID }
phoneNumber = { phoneNumber } />
<a
className = 'more-numbers'
href = {
getDialInfoPageURL(
conferenceName,
locationUrl
)
}
href = { _dialInfoPageUrl }
rel = 'noopener noreferrer'
target = '_blank'>
{ t('info.moreNumbers') }
@ -72,4 +62,20 @@ function DialInSection({
);
}
export default translate(DialInSection);
/**
* Maps (parts of) the Redux state to the associated props for the
* {@code DialInLink} component.
*
* @param {Object} state - The Redux state.
* @private
* @returns {Props}
*/
function _mapStateToProps(state) {
return {
_dialIn: state['features/invite'],
_dialInfoPageUrl: getDialInfoPageURL(state)
};
}
export default translate(connect(_mapStateToProps)(DialInSection));

View File

@ -1,7 +1,11 @@
// @flow
import { getActiveSession } from '../../features/recording/functions';
import { getRoomName } from '../base/conference';
import { getInviteURL } from '../base/connection';
import { i18next } from '../base/i18n';
import { isLocalParticipantModerator } from '../base/participants';
import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
import { getLocalParticipant, isLocalParticipantModerator } from '../base/participants';
import { toState } from '../base/redux';
import { doGetJSON, parseURIString } from '../base/util';
import { isVpaasMeeting } from '../billing-counter/functions';
@ -239,43 +243,44 @@ export function getInviteResultsForQuery(
* @returns {string}
*/
export function getInviteText({
_conferenceName,
_localParticipantName,
_inviteUrl,
_locationUrl,
_dialIn,
_liveStreamViewURL,
state,
phoneNumber,
t
}: Object) {
const inviteURL = _decodeRoomURI(_inviteUrl);
const dialIn = state['features/invite'];
const inviteUrl = getInviteURL(state);
const currentLiveStreamingSession = getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
const liveStreamViewURL
= currentLiveStreamingSession
&& currentLiveStreamingSession.liveStreamViewURL;
const localParticipant = getLocalParticipant(state);
const localParticipantName = localParticipant?.name;
let invite = _localParticipantName
? t('info.inviteURLFirstPartPersonal', { name: _localParticipantName })
const inviteURL = _decodeRoomURI(inviteUrl);
let invite = localParticipantName
? t('info.inviteURLFirstPartPersonal', { name: localParticipantName })
: t('info.inviteURLFirstPartGeneral');
invite += t('info.inviteURLSecondPart', {
url: inviteURL
});
if (_liveStreamViewURL) {
if (liveStreamViewURL) {
const liveStream = t('info.inviteLiveStream', {
url: _liveStreamViewURL
url: liveStreamViewURL
});
invite = `${invite}\n${liveStream}`;
}
if (shouldDisplayDialIn(_dialIn)) {
if (shouldDisplayDialIn(dialIn)) {
const dial = t('info.invitePhone', {
number: phoneNumber,
conferenceID: _dialIn.conferenceID
conferenceID: dialIn.conferenceID
});
const moreNumbers = t('info.invitePhoneAlternatives', {
url: getDialInfoPageURL(
_conferenceName,
_locationUrl
),
url: getDialInfoPageURL(state),
silentUrl: `${inviteURL}#config.startSilent=true`
});
@ -514,9 +519,7 @@ export function getShareInfoText(
.catch(error =>
logger.error('Error fetching numbers or conferenceID', error))
.then(defaultDialInNumber => {
let dialInfoPageUrl = getDialInfoPageURL(
room,
state['features/base/connection'].locationURL);
let dialInfoPageUrl = getDialInfoPageURL(state);
if (useHtml) {
dialInfoPageUrl
@ -537,28 +540,19 @@ export function getShareInfoText(
/**
* Generates the URL for the static dial in info page.
*
* @param {string} conferenceName - The conference name.
* @param {Object} locationURL - The current location URL, the object coming
* from state ['features/base/connection'].locationURL.
* @param {Object} state - The state from the Redux store.
* @returns {string}
*/
export function getDialInfoPageURL(
conferenceName: string,
locationURL: Object) {
const origin = locationURL.origin;
const pathParts = locationURL.pathname.split('/');
export function getDialInfoPageURL(state: Object) {
const { didPageUrl } = state['features/dynamic-branding'];
const conferenceName = getRoomName(state);
const { locationURL } = state['features/base/connection'];
const { href } = locationURL;
const room = _decodeRoomURI(conferenceName);
pathParts.length = pathParts.length - 1;
const url = didPageUrl || `${href.substring(0, href.lastIndexOf('/'))}/static/dialInInfo.html`;
const newPath = pathParts.reduce((accumulator, currentValue) => {
if (currentValue) {
return `${accumulator}/${currentValue}`;
}
return accumulator;
}, '');
return `${origin}${newPath}/static/dialInInfo.html?room=${_decodeRoomURI(conferenceName)}`;
return `${url}?room=${room}`;
}
/**

View File

@ -11,22 +11,16 @@ import { getDialInfoPageURL, shouldDisplayDialIn } from '../../invite';
*/
type Props = {
/**
* The name of the current conference.
*/
_room: string,
/**
* The current location url of the conference.
*/
_locationURL: string,
/**
* The redux state representing the dial-in numbers feature.
*/
_dialIn: Object,
/**
* The url of the page containing the dial-in numbers list.
*/
_dialInfoPageUrl: string,
/**
* Invoked to obtain translated strings.
*/
@ -47,7 +41,7 @@ class DialInLink extends Component<Props> {
* @returns {ReactElement}
*/
render() {
const { _room, _locationURL, _dialIn, t } = this.props;
const { _dialIn, _dialInfoPageUrl, t } = this.props;
if (!shouldDisplayDialIn(_dialIn)) {
return null;
@ -56,12 +50,7 @@ class DialInLink extends Component<Props> {
return (
<div>{t('toolbar.noAudioSignalDialInDesc')}&nbsp;
<a
href = {
getDialInfoPageURL(
_room,
_locationURL
)
}
href = { _dialInfoPageUrl }
rel = 'noopener noreferrer'
target = '_blank'>
{t('toolbar.noAudioSignalDialInLinkDesc')}
@ -77,18 +66,12 @@ class DialInLink extends Component<Props> {
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _room: string,
* _locationURL: string,
* _dialIn: Object,
* }}
* @returns {Props}
*/
function _mapStateToProps(state) {
return {
_room: state['features/base/conference'].room,
_locationURL: state['features/base/connection'].locationURL,
_dialIn: state['features/invite']
_dialIn: state['features/invite'],
_dialInfoPageUrl: getDialInfoPageURL(state)
};
}

View File

@ -4,7 +4,6 @@ declare var JitsiMeetJS: Object;
import uuid from 'uuid';
import { getRoomName } from '../base/conference';
import { getDialOutStatusUrl, getDialOutUrl } from '../base/config/functions';
import { createLocalTrack } from '../base/lib-jitsi-meet';
import {
@ -262,10 +261,7 @@ export function makePrecallTest(conferenceOptions: Object) {
*/
export function openDialInPage() {
return function(dispatch: Function, getState: Function) {
const state = getState();
const locationURL = state['features/base/connection'].locationURL;
const roomName = getRoomName(state);
const dialInPage = getDialInfoPageURL(roomName, locationURL);
const dialInPage = getDialInfoPageURL(getState());
openURLInBrowser(dialInPage, true);
};