Browse Source

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

j8
horymury 4 years ago
parent
commit
79bb98dab3
No account linked to committer's email address

+ 10
- 0
react/features/dynamic-branding/reducer.js View File

58
      */
58
      */
59
     defaultBranding: true,
59
     defaultBranding: true,
60
 
60
 
61
+    /**
62
+     * Url for a custom page for DID numbers list.
63
+     *
64
+     * @public
65
+     * @type {string}
66
+     */
67
+    didPageUrl: '',
68
+
61
     /**
69
     /**
62
      * The custom invite domain.
70
      * The custom invite domain.
63
      *
71
      *
101
             backgroundColor,
109
             backgroundColor,
102
             backgroundImageUrl,
110
             backgroundImageUrl,
103
             defaultBranding,
111
             defaultBranding,
112
+            didPageUrl,
104
             inviteDomain,
113
             inviteDomain,
105
             logoClickUrl,
114
             logoClickUrl,
106
             logoImageUrl
115
             logoImageUrl
110
             backgroundColor,
119
             backgroundColor,
111
             backgroundImageUrl,
120
             backgroundImageUrl,
112
             defaultBranding,
121
             defaultBranding,
122
+            didPageUrl,
113
             inviteDomain,
123
             inviteDomain,
114
             logoClickUrl,
124
             logoClickUrl,
115
             logoImageUrl,
125
             logoImageUrl,

+ 21
- 52
react/features/invite/components/add-people-dialog/web/AddPeopleDialog.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
-import React, { useState, useEffect } from 'react';
3
+import React, { useEffect } from 'react';
4
 
4
 
5
 import { createInviteDialogEvent, sendAnalytics } from '../../../../analytics';
5
 import { createInviteDialogEvent, sendAnalytics } from '../../../../analytics';
6
-import { getRoomName } from '../../../../base/conference';
7
 import { getInviteURL } from '../../../../base/connection';
6
 import { getInviteURL } from '../../../../base/connection';
8
 import { Dialog } from '../../../../base/dialog';
7
 import { Dialog } from '../../../../base/dialog';
9
 import { translate } from '../../../../base/i18n';
8
 import { translate } from '../../../../base/i18n';
10
 import { JitsiRecordingConstants } from '../../../../base/lib-jitsi-meet';
9
 import { JitsiRecordingConstants } from '../../../../base/lib-jitsi-meet';
11
-import { getLocalParticipant } from '../../../../base/participants';
12
 import { connect } from '../../../../base/redux';
10
 import { connect } from '../../../../base/redux';
13
 import { isVpaasMeeting } from '../../../../billing-counter/functions';
11
 import { isVpaasMeeting } from '../../../../billing-counter/functions';
14
 import EmbedMeetingTrigger from '../../../../embed-meeting/components/EmbedMeetingTrigger';
12
 import EmbedMeetingTrigger from '../../../../embed-meeting/components/EmbedMeetingTrigger';
26
 
24
 
27
 type Props = {
25
 type Props = {
28
 
26
 
29
-    /**
30
-     * The name of the current conference. Used as part of inviting users.
31
-     */
32
-    _conferenceName: string,
33
-
34
     /**
27
     /**
35
      * The object representing the dialIn feature.
28
      * The object representing the dialIn feature.
36
      */
29
      */
41
      */
34
      */
42
     _embedMeetingVisible: boolean,
35
     _embedMeetingVisible: boolean,
43
 
36
 
37
+    /**
38
+     * The meeting invitation text.
39
+     */
40
+    _invitationText: string,
41
+
44
     /**
42
     /**
45
      * Whether or not invite contacts should be visible.
43
      * Whether or not invite contacts should be visible.
46
      */
44
      */
57
     _liveStreamViewURL: string,
55
     _liveStreamViewURL: string,
58
 
56
 
59
     /**
57
     /**
60
-     * The redux representation of the local participant.
61
-     */
62
-    _localParticipantName: ?string,
63
-
64
-    /**
65
-     * The current location url of the conference.
58
+     * The default phone number.
66
      */
59
      */
67
-    _locationUrl: Object,
60
+    _phoneNumber: ?string,
68
 
61
 
69
     /**
62
     /**
70
      * Invoked to obtain translated strings.
63
      * Invoked to obtain translated strings.
83
  * @returns {React$Element<any>}
76
  * @returns {React$Element<any>}
84
  */
77
  */
85
 function AddPeopleDialog({
78
 function AddPeopleDialog({
86
-    _conferenceName,
87
     _dialIn,
79
     _dialIn,
88
     _embedMeetingVisible,
80
     _embedMeetingVisible,
81
+    _invitationText,
89
     _inviteContactsVisible,
82
     _inviteContactsVisible,
90
     _inviteUrl,
83
     _inviteUrl,
91
     _liveStreamViewURL,
84
     _liveStreamViewURL,
92
-    _localParticipantName,
93
-    _locationUrl,
85
+    _phoneNumber,
94
     t,
86
     t,
95
     updateNumbers }: Props) {
87
     updateNumbers }: Props) {
96
-    const [ phoneNumber, setPhoneNumber ] = useState(undefined);
97
 
88
 
98
     /**
89
     /**
99
      * Updates the dial-in numbers.
90
      * Updates the dial-in numbers.
119
         };
110
         };
120
     }, []);
111
     }, []);
121
 
112
 
122
-    /**
123
-     * Updates the phone number in the state once the dial-in numbers are fetched.
124
-     *
125
-     * @returns {void}
126
-     */
127
-    useEffect(() => {
128
-        if (!phoneNumber && _dialIn && _dialIn.numbers) {
129
-            setPhoneNumber(_getDefaultPhoneNumber(_dialIn.numbers));
130
-        }
131
-    }, [ _dialIn ]);
132
-
133
-    const invite = getInviteText({
134
-        _conferenceName,
135
-        _localParticipantName,
136
-        _inviteUrl,
137
-        _locationUrl,
138
-        _dialIn,
139
-        _liveStreamViewURL,
140
-        phoneNumber,
141
-        t
142
-    });
143
     const inviteSubject = t('addPeople.inviteMoreMailSubject', {
113
     const inviteSubject = t('addPeople.inviteMoreMailSubject', {
144
         appName: interfaceConfig.APP_NAME
114
         appName: interfaceConfig.APP_NAME
145
     });
115
     });
156
                 <CopyMeetingLinkSection url = { _inviteUrl } />
126
                 <CopyMeetingLinkSection url = { _inviteUrl } />
157
                 <InviteByEmailSection
127
                 <InviteByEmailSection
158
                     inviteSubject = { inviteSubject }
128
                     inviteSubject = { inviteSubject }
159
-                    inviteText = { invite } />
129
+                    inviteText = { _invitationText } />
160
                 { _embedMeetingVisible && <EmbedMeetingTrigger /> }
130
                 { _embedMeetingVisible && <EmbedMeetingTrigger /> }
161
                 <div className = 'invite-more-dialog separator' />
131
                 <div className = 'invite-more-dialog separator' />
162
                 {
132
                 {
165
                 }
135
                 }
166
                 {
136
                 {
167
                     _dialIn.numbers
137
                     _dialIn.numbers
168
-                        && <DialInSection
169
-                            conferenceName = { _conferenceName }
170
-                            dialIn = { _dialIn }
171
-                            locationUrl = { _locationUrl }
172
-                            phoneNumber = { phoneNumber } />
138
+                        && <DialInSection phoneNumber = { _phoneNumber } />
173
                 }
139
                 }
174
             </div>
140
             </div>
175
         </Dialog>
141
         </Dialog>
181
  * {@code AddPeopleDialog} component.
147
  * {@code AddPeopleDialog} component.
182
  *
148
  *
183
  * @param {Object} state - The Redux state.
149
  * @param {Object} state - The Redux state.
150
+ * @param {Object} ownProps - The properties explicitly passed to the component.
184
  * @private
151
  * @private
185
  * @returns {Props}
152
  * @returns {Props}
186
  */
153
  */
187
-function mapStateToProps(state) {
188
-    const localParticipant = getLocalParticipant(state);
154
+function mapStateToProps(state, ownProps) {
189
     const currentLiveStreamingSession
155
     const currentLiveStreamingSession
190
         = getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
156
         = getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
191
     const { iAmRecorder } = state['features/base/config'];
157
     const { iAmRecorder } = state['features/base/config'];
192
     const addPeopleEnabled = isAddPeopleEnabled(state);
158
     const addPeopleEnabled = isAddPeopleEnabled(state);
193
     const dialOutEnabled = isDialOutEnabled(state);
159
     const dialOutEnabled = isDialOutEnabled(state);
194
     const hideInviteContacts = iAmRecorder || (!addPeopleEnabled && !dialOutEnabled);
160
     const hideInviteContacts = iAmRecorder || (!addPeopleEnabled && !dialOutEnabled);
161
+    const dialIn = state['features/invite'];
162
+    const phoneNumber = dialIn && dialIn.numbers ? _getDefaultPhoneNumber(dialIn.numbers) : undefined;
195
 
163
 
196
     return {
164
     return {
197
-        _conferenceName: getRoomName(state),
198
-        _dialIn: state['features/invite'],
165
+        _dialIn: dialIn,
199
         _embedMeetingVisible: !isVpaasMeeting(state),
166
         _embedMeetingVisible: !isVpaasMeeting(state),
167
+        _invitationText: getInviteText({ state,
168
+            phoneNumber,
169
+            t: ownProps.t }),
200
         _inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts,
170
         _inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts,
201
         _inviteUrl: getInviteURL(state),
171
         _inviteUrl: getInviteURL(state),
202
         _liveStreamViewURL:
172
         _liveStreamViewURL:
203
             currentLiveStreamingSession
173
             currentLiveStreamingSession
204
                 && currentLiveStreamingSession.liveStreamViewURL,
174
                 && currentLiveStreamingSession.liveStreamViewURL,
205
-        _localParticipantName: localParticipant?.name,
206
-        _locationUrl: state['features/base/connection'].locationURL
175
+        _phoneNumber: phoneNumber
207
     };
176
     };
208
 }
177
 }
209
 
178
 

+ 25
- 19
react/features/invite/components/add-people-dialog/web/DialInSection.js View File

3
 import React from 'react';
3
 import React from 'react';
4
 
4
 
5
 import { translate } from '../../../../base/i18n';
5
 import { translate } from '../../../../base/i18n';
6
+import { connect } from '../../../../base/redux';
6
 import { getDialInfoPageURL } from '../../../functions';
7
 import { getDialInfoPageURL } from '../../../functions';
7
 
8
 
8
 import DialInNumber from './DialInNumber';
9
 import DialInNumber from './DialInNumber';
9
 
10
 
10
 type Props = {
11
 type Props = {
11
 
12
 
12
-    /**
13
-     * The name of the current conference. Used as part of inviting users.
14
-     */
15
-    conferenceName: string,
16
-
17
     /**
13
     /**
18
      * The object representing the dialIn feature.
14
      * The object representing the dialIn feature.
19
      */
15
      */
20
-    dialIn: Object,
16
+    _dialIn: Object,
21
 
17
 
22
     /**
18
     /**
23
-     * The current location url of the conference.
19
+     * The url of the page containing the dial-in numbers list.
24
      */
20
      */
25
-    locationUrl: Object,
21
+    _dialInfoPageUrl: string,
26
 
22
 
27
     /**
23
     /**
28
      * The phone number to dial to begin the process of dialing into a
24
      * The phone number to dial to begin the process of dialing into a
45
  * @returns {null|ReactElement}
41
  * @returns {null|ReactElement}
46
  */
42
  */
47
 function DialInSection({
43
 function DialInSection({
48
-    conferenceName,
49
-    dialIn,
50
-    locationUrl,
44
+    _dialIn,
45
+    _dialInfoPageUrl,
51
     phoneNumber,
46
     phoneNumber,
52
     t
47
     t
53
 }: Props) {
48
 }: Props) {
54
     return (
49
     return (
55
         <div className = 'invite-more-dialog dial-in-display'>
50
         <div className = 'invite-more-dialog dial-in-display'>
56
             <DialInNumber
51
             <DialInNumber
57
-                conferenceID = { dialIn.conferenceID }
52
+                conferenceID = { _dialIn.conferenceID }
58
                 phoneNumber = { phoneNumber } />
53
                 phoneNumber = { phoneNumber } />
59
             <a
54
             <a
60
                 className = 'more-numbers'
55
                 className = 'more-numbers'
61
-                href = {
62
-                    getDialInfoPageURL(
63
-                        conferenceName,
64
-                        locationUrl
65
-                    )
66
-                }
56
+                href = { _dialInfoPageUrl }
67
                 rel = 'noopener noreferrer'
57
                 rel = 'noopener noreferrer'
68
                 target = '_blank'>
58
                 target = '_blank'>
69
                 { t('info.moreNumbers') }
59
                 { t('info.moreNumbers') }
72
     );
62
     );
73
 }
63
 }
74
 
64
 
75
-export default translate(DialInSection);
65
+
66
+/**
67
+ * Maps (parts of) the Redux state to the associated props for the
68
+ * {@code DialInLink} component.
69
+ *
70
+ * @param {Object} state - The Redux state.
71
+ * @private
72
+ * @returns {Props}
73
+ */
74
+function _mapStateToProps(state) {
75
+    return {
76
+        _dialIn: state['features/invite'],
77
+        _dialInfoPageUrl: getDialInfoPageURL(state)
78
+    };
79
+}
80
+
81
+export default translate(connect(_mapStateToProps)(DialInSection));

+ 34
- 40
react/features/invite/functions.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { getActiveSession } from '../../features/recording/functions';
4
+import { getRoomName } from '../base/conference';
5
+import { getInviteURL } from '../base/connection';
3
 import { i18next } from '../base/i18n';
6
 import { i18next } from '../base/i18n';
4
-import { isLocalParticipantModerator } from '../base/participants';
7
+import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
8
+import { getLocalParticipant, isLocalParticipantModerator } from '../base/participants';
5
 import { toState } from '../base/redux';
9
 import { toState } from '../base/redux';
6
 import { doGetJSON, parseURIString } from '../base/util';
10
 import { doGetJSON, parseURIString } from '../base/util';
7
 import { isVpaasMeeting } from '../billing-counter/functions';
11
 import { isVpaasMeeting } from '../billing-counter/functions';
239
  * @returns {string}
243
  * @returns {string}
240
  */
244
  */
241
 export function getInviteText({
245
 export function getInviteText({
242
-    _conferenceName,
243
-    _localParticipantName,
244
-    _inviteUrl,
245
-    _locationUrl,
246
-    _dialIn,
247
-    _liveStreamViewURL,
246
+    state,
248
     phoneNumber,
247
     phoneNumber,
249
     t
248
     t
250
 }: Object) {
249
 }: Object) {
251
-    const inviteURL = _decodeRoomURI(_inviteUrl);
252
-
253
-    let invite = _localParticipantName
254
-        ? t('info.inviteURLFirstPartPersonal', { name: _localParticipantName })
250
+    const dialIn = state['features/invite'];
251
+    const inviteUrl = getInviteURL(state);
252
+    const currentLiveStreamingSession = getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
253
+    const liveStreamViewURL
254
+        = currentLiveStreamingSession
255
+            && currentLiveStreamingSession.liveStreamViewURL;
256
+    const localParticipant = getLocalParticipant(state);
257
+    const localParticipantName = localParticipant?.name;
258
+
259
+    const inviteURL = _decodeRoomURI(inviteUrl);
260
+
261
+    let invite = localParticipantName
262
+        ? t('info.inviteURLFirstPartPersonal', { name: localParticipantName })
255
         : t('info.inviteURLFirstPartGeneral');
263
         : t('info.inviteURLFirstPartGeneral');
256
 
264
 
257
     invite += t('info.inviteURLSecondPart', {
265
     invite += t('info.inviteURLSecondPart', {
258
         url: inviteURL
266
         url: inviteURL
259
     });
267
     });
260
 
268
 
261
-    if (_liveStreamViewURL) {
269
+    if (liveStreamViewURL) {
262
         const liveStream = t('info.inviteLiveStream', {
270
         const liveStream = t('info.inviteLiveStream', {
263
-            url: _liveStreamViewURL
271
+            url: liveStreamViewURL
264
         });
272
         });
265
 
273
 
266
         invite = `${invite}\n${liveStream}`;
274
         invite = `${invite}\n${liveStream}`;
267
     }
275
     }
268
 
276
 
269
-    if (shouldDisplayDialIn(_dialIn)) {
277
+    if (shouldDisplayDialIn(dialIn)) {
270
         const dial = t('info.invitePhone', {
278
         const dial = t('info.invitePhone', {
271
             number: phoneNumber,
279
             number: phoneNumber,
272
-            conferenceID: _dialIn.conferenceID
280
+            conferenceID: dialIn.conferenceID
273
         });
281
         });
274
         const moreNumbers = t('info.invitePhoneAlternatives', {
282
         const moreNumbers = t('info.invitePhoneAlternatives', {
275
-            url: getDialInfoPageURL(
276
-                _conferenceName,
277
-                _locationUrl
278
-            ),
283
+            url: getDialInfoPageURL(state),
279
             silentUrl: `${inviteURL}#config.startSilent=true`
284
             silentUrl: `${inviteURL}#config.startSilent=true`
280
         });
285
         });
281
 
286
 
514
             .catch(error =>
519
             .catch(error =>
515
                 logger.error('Error fetching numbers or conferenceID', error))
520
                 logger.error('Error fetching numbers or conferenceID', error))
516
             .then(defaultDialInNumber => {
521
             .then(defaultDialInNumber => {
517
-                let dialInfoPageUrl = getDialInfoPageURL(
518
-                    room,
519
-                    state['features/base/connection'].locationURL);
522
+                let dialInfoPageUrl = getDialInfoPageURL(state);
520
 
523
 
521
                 if (useHtml) {
524
                 if (useHtml) {
522
                     dialInfoPageUrl
525
                     dialInfoPageUrl
537
 /**
540
 /**
538
  * Generates the URL for the static dial in info page.
541
  * Generates the URL for the static dial in info page.
539
  *
542
  *
540
- * @param {string} conferenceName - The conference name.
541
- * @param {Object} locationURL - The current location URL, the object coming
542
- * from state ['features/base/connection'].locationURL.
543
+ * @param {Object} state - The state from the Redux store.
543
  * @returns {string}
544
  * @returns {string}
544
  */
545
  */
545
-export function getDialInfoPageURL(
546
-        conferenceName: string,
547
-        locationURL: Object) {
548
-    const origin = locationURL.origin;
549
-    const pathParts = locationURL.pathname.split('/');
550
-
551
-    pathParts.length = pathParts.length - 1;
552
-
553
-    const newPath = pathParts.reduce((accumulator, currentValue) => {
554
-        if (currentValue) {
555
-            return `${accumulator}/${currentValue}`;
556
-        }
546
+export function getDialInfoPageURL(state: Object) {
547
+    const { didPageUrl } = state['features/dynamic-branding'];
548
+    const conferenceName = getRoomName(state);
549
+    const { locationURL } = state['features/base/connection'];
550
+    const { href } = locationURL;
551
+    const room = _decodeRoomURI(conferenceName);
557
 
552
 
558
-        return accumulator;
559
-    }, '');
553
+    const url = didPageUrl || `${href.substring(0, href.lastIndexOf('/'))}/static/dialInInfo.html`;
560
 
554
 
561
-    return `${origin}${newPath}/static/dialInInfo.html?room=${_decodeRoomURI(conferenceName)}`;
555
+    return `${url}?room=${room}`;
562
 }
556
 }
563
 
557
 
564
 /**
558
 /**

+ 10
- 27
react/features/no-audio-signal/components/DialInLink.js View File

12
 type Props = {
12
 type Props = {
13
 
13
 
14
     /**
14
     /**
15
-     * The name of the current conference.
16
-     */
17
-    _room: string,
18
-
19
-    /**
20
-     * The current location url of the conference.
15
+     * The redux state representing the dial-in numbers feature.
21
      */
16
      */
22
-    _locationURL: string,
23
-
17
+    _dialIn: Object,
24
 
18
 
25
     /**
19
     /**
26
-     * The redux state representing the dial-in numbers feature.
20
+     * The url of the page containing the dial-in numbers list.
27
      */
21
      */
28
-    _dialIn: Object,
22
+    _dialInfoPageUrl: string,
29
 
23
 
30
     /**
24
     /**
31
      * Invoked to obtain translated strings.
25
      * Invoked to obtain translated strings.
47
      * @returns {ReactElement}
41
      * @returns {ReactElement}
48
      */
42
      */
49
     render() {
43
     render() {
50
-        const { _room, _locationURL, _dialIn, t } = this.props;
44
+        const { _dialIn, _dialInfoPageUrl, t } = this.props;
51
 
45
 
52
         if (!shouldDisplayDialIn(_dialIn)) {
46
         if (!shouldDisplayDialIn(_dialIn)) {
53
             return null;
47
             return null;
56
         return (
50
         return (
57
             <div>{t('toolbar.noAudioSignalDialInDesc')}&nbsp;
51
             <div>{t('toolbar.noAudioSignalDialInDesc')}&nbsp;
58
                 <a
52
                 <a
59
-                    href = {
60
-                        getDialInfoPageURL(
61
-                            _room,
62
-                            _locationURL
63
-                        )
64
-                    }
53
+                    href = { _dialInfoPageUrl }
65
                     rel = 'noopener noreferrer'
54
                     rel = 'noopener noreferrer'
66
                     target = '_blank'>
55
                     target = '_blank'>
67
                     {t('toolbar.noAudioSignalDialInLinkDesc')}
56
                     {t('toolbar.noAudioSignalDialInLinkDesc')}
77
  *
66
  *
78
  * @param {Object} state - The Redux state.
67
  * @param {Object} state - The Redux state.
79
  * @private
68
  * @private
80
- * @returns {{
81
-    *     _room: string,
82
-    *     _locationURL: string,
83
-    *     _dialIn: Object,
84
-    * }}
85
-    */
69
+ * @returns {Props}
70
+ */
86
 function _mapStateToProps(state) {
71
 function _mapStateToProps(state) {
87
-
88
     return {
72
     return {
89
-        _room: state['features/base/conference'].room,
90
-        _locationURL: state['features/base/connection'].locationURL,
91
-        _dialIn: state['features/invite']
73
+        _dialIn: state['features/invite'],
74
+        _dialInfoPageUrl: getDialInfoPageURL(state)
92
     };
75
     };
93
 }
76
 }
94
 
77
 

+ 1
- 5
react/features/prejoin/actions.js View File

4
 
4
 
5
 import uuid from 'uuid';
5
 import uuid from 'uuid';
6
 
6
 
7
-import { getRoomName } from '../base/conference';
8
 import { getDialOutStatusUrl, getDialOutUrl } from '../base/config/functions';
7
 import { getDialOutStatusUrl, getDialOutUrl } from '../base/config/functions';
9
 import { createLocalTrack } from '../base/lib-jitsi-meet';
8
 import { createLocalTrack } from '../base/lib-jitsi-meet';
10
 import {
9
 import {
262
  */
261
  */
263
 export function openDialInPage() {
262
 export function openDialInPage() {
264
     return function(dispatch: Function, getState: Function) {
263
     return function(dispatch: Function, getState: Function) {
265
-        const state = getState();
266
-        const locationURL = state['features/base/connection'].locationURL;
267
-        const roomName = getRoomName(state);
268
-        const dialInPage = getDialInfoPageURL(roomName, locationURL);
264
+        const dialInPage = getDialInfoPageURL(getState());
269
 
265
 
270
         openURLInBrowser(dialInPage, true);
266
         openURLInBrowser(dialInPage, true);
271
     };
267
     };

Loading…
Cancel
Save