Explorar el Código

Merge pull request #9204 from jitsi/tavram/sip-fixes

fix(sip) allow sip invites to contain phone numbers
j8
Avram Tudor hace 4 años
padre
commit
7db9fc94e2
No account linked to committer's email address

+ 5
- 8
lang/main.json Ver fichero

@@ -5,6 +5,7 @@
5 5
         "copyInvite": "Copy meeting invitation",
6 6
         "copyLink": "Copy meeting link",
7 7
         "copyStream": "Copy live streaming link",
8
+        "contacts": "contacts",
8 9
         "countryNotSupported": "We do not support this destination yet.",
9 10
         "countryReminder": "Calling outside the US? Please make sure you start with the country code!",
10 11
         "defaultEmail": "Your Default Email",
@@ -16,19 +17,14 @@
16 17
         "inviteMoreMailSubject": "Join {{appName}} meeting",
17 18
         "inviteMorePrompt": "Invite more people",
18 19
         "linkCopied": "Link copied to clipboard",
19
-        "loading": "Searching for people and phone numbers",
20
-        "loadingNumber": "Validating phone number",
21
-        "loadingPeople": "Searching for people to invite",
22 20
         "noResults": "No matching search results",
23
-        "noValidNumbers": "Please enter a phone number",
24 21
         "outlookEmail": "Outlook Email",
25
-        "searchNumbers": "Add phone numbers",
26
-        "searchPeople": "Search for people",
27
-        "searchPeopleAndNumbers": "Search for people or add their phone numbers",
22
+        "phoneNumbers": "phone numbers",
23
+        "searching": "Searching...",
28 24
         "shareInvite": "Share meeting invitation",
29 25
         "shareLink": "Share the meeting link to invite others",
30 26
         "shareStream": "Share the live streaming link",
31
-        "sip": "SIP: {{address}}",
27
+        "sipAddresses": "sip addresses",
32 28
         "telephone": "Telephone: {{number}}",
33 29
         "title": "Invite people to this meeting",
34 30
         "yahooEmail": "Yahoo Email"
@@ -379,6 +375,7 @@
379 375
         "inviteLiveStream": "To view the live stream of this meeting, click this link: {{url}}",
380 376
         "invitePhone": "To join by phone instead, tap this: {{number}},,{{conferenceID}}#\n",
381 377
         "invitePhoneAlternatives": "Looking for a different dial-in number?\nSee meeting dial-in numbers: {{url}}\n\n\nIf also dialing-in through a room phone, join without connecting to audio: {{silentUrl}}",
378
+        "inviteSipEndpoint": "To join using the SIP address, enter this: {{sipUri}}",
382 379
         "inviteURLFirstPartGeneral": "You are invited to join a meeting.",
383 380
         "inviteURLFirstPartPersonal": "{{name}} is inviting you to a meeting.\n",
384 381
         "inviteURLSecondPart": "\nJoin the meeting:\n{{url}}\n",

+ 3
- 2
react/features/invite/actions.any.js Ver fichero

@@ -215,7 +215,7 @@ export function updateDialInNumbers() {
215 215
             getDialInNumbers(dialInNumbersUrl, room, mucURL),
216 216
             getDialInConferenceID(dialInConfCodeUrl, room, mucURL)
217 217
         ])
218
-            .then(([ dialInNumbers, { conference, id, message } ]) => {
218
+            .then(([ dialInNumbers, { conference, id, message, sipUri } ]) => {
219 219
                 if (!conference || !id) {
220 220
                     return Promise.reject(message);
221 221
                 }
@@ -223,7 +223,8 @@ export function updateDialInNumbers() {
223 223
                 dispatch({
224 224
                     type: UPDATE_DIAL_IN_NUMBERS_SUCCESS,
225 225
                     conferenceID: id,
226
-                    dialInNumbers
226
+                    dialInNumbers,
227
+                    sipUri
227 228
                 });
228 229
             })
229 230
             .catch(error => {

+ 31
- 20
react/features/invite/components/add-people-dialog/web/InviteContactsForm.js Ver fichero

@@ -57,6 +57,8 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
57 57
 
58 58
     _resourceClient: Object;
59 59
 
60
+    _translations: Object;
61
+
60 62
     state = {
61 63
         addToCallError: false,
62 64
         addToCallInProgress: false,
@@ -86,6 +88,16 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
86 88
             makeQuery: this._query,
87 89
             parseResults: this._parseQueryResults
88 90
         };
91
+
92
+
93
+        const { t } = props;
94
+
95
+        this._translations = {
96
+            _dialOutEnabled: t('addPeople.phoneNumbers'),
97
+            _addPeopleEnabled: t('addPeople.contacts'),
98
+            _sipInviteEnabled: t('addPeople.sipAddresses')
99
+        };
100
+
89 101
     }
90 102
 
91 103
     /**
@@ -118,30 +130,29 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
118 130
             _addPeopleEnabled,
119 131
             _dialOutEnabled,
120 132
             _isVpaas,
133
+            _sipInviteEnabled,
121 134
             t
122 135
         } = this.props;
123 136
         const footerText = this._renderFooterText();
124 137
         let isMultiSelectDisabled = this.state.addToCallInProgress;
125
-        let placeholder;
126
-        let loadingMessage;
127
-        let noMatches;
128
-
129
-        if (_addPeopleEnabled && _dialOutEnabled) {
130
-            loadingMessage = 'addPeople.loading';
131
-            noMatches = 'addPeople.noResults';
132
-            placeholder = 'addPeople.searchPeopleAndNumbers';
133
-        } else if (_addPeopleEnabled) {
134
-            loadingMessage = 'addPeople.loadingPeople';
135
-            noMatches = 'addPeople.noResults';
136
-            placeholder = 'addPeople.searchPeople';
137
-        } else if (_dialOutEnabled) {
138
-            loadingMessage = 'addPeople.loadingNumber';
139
-            noMatches = 'addPeople.noValidNumbers';
140
-            placeholder = 'addPeople.searchNumbers';
141
-        } else {
138
+        const loadingMessage = 'addPeople.searching';
139
+        const noMatches = 'addPeople.noResults';
140
+
141
+        const features = {
142
+            _dialOutEnabled,
143
+            _addPeopleEnabled,
144
+            _sipInviteEnabled
145
+        };
146
+
147
+        const computedPlaceholder = Object.keys(features)
148
+            .filter(v => Boolean(features[v]))
149
+            .map(v => this._translations[v])
150
+            .join(', ');
151
+
152
+        const placeholder = computedPlaceholder ? `${t('dialog.add')} ${computedPlaceholder}` : t('addPeople.disabled');
153
+
154
+        if (!computedPlaceholder) {
142 155
             isMultiSelectDisabled = true;
143
-            noMatches = 'addPeople.noResults';
144
-            placeholder = 'addPeople.disabled';
145 156
         }
146 157
 
147 158
         return (
@@ -156,7 +167,7 @@ class InviteContactsForm extends AbstractAddPeopleDialog<Props, State> {
156 167
                     noMatchesFound = { t(noMatches) }
157 168
                     onItemSelected = { this._onItemSelected }
158 169
                     onSelectionChange = { this._onSelectionChange }
159
-                    placeholder = { t(placeholder) }
170
+                    placeholder = { placeholder }
160 171
                     ref = { this._setMultiSelectElement }
161 172
                     resourceClient = { this._resourceClient }
162 173
                     shouldFitContainer = { true }

+ 1
- 1
react/features/invite/constants.js Ver fichero

@@ -47,7 +47,7 @@ export const OUTGOING_CALL_START_SOUND_ID = 'OUTGOING_CALL_START_SOUND_ID';
47 47
  * Regex for matching sip addresses.
48 48
  */
49 49
 // eslint-disable-next-line max-len
50
-export const SIP_ADDRESS_REGEX = /^[a-zA-Z]+(?:([^\s>:@]+)(?::([^\s@>]+))?@)?([\w\-.]+)(?::(\d+))?((?:;[^\s=?>;]+(?:=[^\s?;]+)?)*)(?:\?(([^\s&=>]+=[^\s&=>]+)(&[^\s&=>]+=[^\s&=>]+)*))?$/;
50
+export const SIP_ADDRESS_REGEX = /^[+a-zA-Z0-9]+(?:([^\s>:@]+)(?::([^\s@>]+))?@)?([\w\-.]+)(?::(\d+))?((?:;[^\s=?>;]+(?:=[^\s?;]+)?)*)(?:\?(([^\s&=>]+=[^\s&=>]+)(&[^\s&=>]+=[^\s&=>]+)*))?$/;
51 51
 
52 52
 /**
53 53
  * Different invite types mapping

+ 8
- 0
react/features/invite/functions.js Ver fichero

@@ -301,6 +301,14 @@ export function getInviteText({
301 301
         invite = `${invite}\n${dial}\n${moreNumbers}`;
302 302
     }
303 303
 
304
+    if (dialIn.sipUri) {
305
+        const sipText = t('info.inviteSipEndpoint', {
306
+            sipUri: dialIn.sipUri
307
+        });
308
+
309
+        invite = `${invite}\n${sipText}`;
310
+    }
311
+
304 312
     return invite;
305 313
 }
306 314
 

+ 1
- 0
react/features/invite/reducer.js Ver fichero

@@ -60,6 +60,7 @@ ReducerRegistry.register('features/invite', (state = DEFAULT_STATE, action) => {
60 60
                 ...state,
61 61
                 conferenceID: action.conferenceID,
62 62
                 numbers: action.dialInNumbers,
63
+                sipUri: action.sipUri,
63 64
                 numbersEnabled: true,
64 65
                 numbersFetched: true
65 66
             };

+ 8
- 1
react/features/lobby/components/AbstractLobbyScreen.js Ver fichero

@@ -46,6 +46,11 @@ export type Props = {
46 46
      */
47 47
     _passwordJoinFailed: boolean,
48 48
 
49
+    /**
50
+     * True if the password field should be available for lobby participants.
51
+     */
52
+     _renderPassword: boolean,
53
+
49 54
     /**
50 55
      * The Redux dispatch function.
51 56
      */
@@ -365,6 +370,7 @@ export function _mapStateToProps(state: Object): $Shape<Props> {
365 370
     const localParticipant = getLocalParticipant(state);
366 371
     const participantId = localParticipant?.id;
367 372
     const { knocking, passwordJoinFailed } = state['features/lobby'];
373
+    const { iAmSipGateway } = state['features/base/config'];
368 374
 
369 375
     return {
370 376
         _knocking: knocking,
@@ -372,6 +378,7 @@ export function _mapStateToProps(state: Object): $Shape<Props> {
372 378
         _participantEmail: localParticipant?.email,
373 379
         _participantId: participantId,
374 380
         _participantName: localParticipant?.name,
375
-        _passwordJoinFailed: passwordJoinFailed
381
+        _passwordJoinFailed: passwordJoinFailed,
382
+        _renderPassword: !iAmSipGateway
376 383
     };
377 384
 }

+ 3
- 3
react/features/lobby/components/native/LobbyScreen.js Ver fichero

@@ -208,7 +208,7 @@ class LobbyScreen extends AbstractLobbyScreen {
208 208
      * @inheritdoc
209 209
      */
210 210
     _renderStandardButtons() {
211
-        const { _knocking, t } = this.props;
211
+        const { _knocking, _renderPassword, t } = this.props;
212 212
 
213 213
         return (
214 214
             <>
@@ -223,7 +223,7 @@ class LobbyScreen extends AbstractLobbyScreen {
223 223
                         { t('lobby.knockButton') }
224 224
                     </Text>
225 225
                 </TouchableOpacity> }
226
-                <TouchableOpacity
226
+                { _renderPassword && <TouchableOpacity
227 227
                     onPress = { this._onSwitchToPasswordMode }
228 228
                     style = { [
229 229
                         styles.button,
@@ -232,7 +232,7 @@ class LobbyScreen extends AbstractLobbyScreen {
232 232
                     <Text>
233 233
                         { t('lobby.enterPasswordButton') }
234 234
                     </Text>
235
-                </TouchableOpacity>
235
+                </TouchableOpacity> }
236 236
             </>
237 237
         );
238 238
     }

+ 3
- 3
react/features/lobby/components/web/LobbyScreen.js Ver fichero

@@ -152,7 +152,7 @@ class LobbyScreen extends AbstractLobbyScreen {
152 152
      * @inheritdoc
153 153
      */
154 154
     _renderStandardButtons() {
155
-        const { _knocking, t } = this.props;
155
+        const { _knocking, _renderPassword, t } = this.props;
156 156
 
157 157
         return (
158 158
             <>
@@ -163,12 +163,12 @@ class LobbyScreen extends AbstractLobbyScreen {
163 163
                     type = 'primary'>
164 164
                     { t('lobby.knockButton') }
165 165
                 </ActionButton> }
166
-                <ActionButton
166
+                {_renderPassword && <ActionButton
167 167
                     onClick = { this._onSwitchToPasswordMode }
168 168
                     testId = 'lobby.enterPasswordButton'
169 169
                     type = 'secondary'>
170 170
                     { t('lobby.enterPasswordButton') }
171
-                </ActionButton>
171
+                </ActionButton> }
172 172
             </>
173 173
         );
174 174
     }

Loading…
Cancelar
Guardar