Просмотр исходного кода

Room lock update (#4394)

* Adds a notification when remote lock happens.

* Updates translations.

Removes unused strings and extracts room password to separate translation, to be able to change it when deployment uses only digits.

* Formats the conference pin when showing it.

* Removes member from translation in favour of participant.

* Updates formatting of the pin.

* Adds a notification when password is remotely removed.
master
Дамян Минков 6 лет назад
Родитель
Сommit
625d268373
Аккаунт пользователя с таким Email не найден

+ 24
- 55
lang/main.json Просмотреть файл

4
         "countryNotSupported": "We do not support this destination yet.",
4
         "countryNotSupported": "We do not support this destination yet.",
5
         "countryReminder": "Calling outside the US? Please make sure you start with the country code!",
5
         "countryReminder": "Calling outside the US? Please make sure you start with the country code!",
6
         "disabled": "You can't invite people.",
6
         "disabled": "You can't invite people.",
7
-        "failedToAdd": "Failed to add members",
7
+        "failedToAdd": "Failed to add participants",
8
         "footerText": "Dialing out is disabled.",
8
         "footerText": "Dialing out is disabled.",
9
         "invite": "Invite",
9
         "invite": "Invite",
10
         "loading": "Searching for people and phone numbers",
10
         "loading": "Searching for people and phone numbers",
112
         "transport_plural": "Transports:",
112
         "transport_plural": "Transports:",
113
         "turn": " (turn)"
113
         "turn": " (turn)"
114
     },
114
     },
115
-    "contactlist_plural": "__count__ Members",
116
     "dateUtils": {
115
     "dateUtils": {
117
         "earlier": "Earlier",
116
         "earlier": "Earlier",
118
         "today": "Today",
117
         "today": "Today",
148
             "liveStreaming": "Live Stream"
147
             "liveStreaming": "Live Stream"
149
         },
148
         },
150
         "allow": "Allow",
149
         "allow": "Allow",
151
-        "alreadySharedVideoMsg": "Another member is already sharing a video. This conference allows only one shared video at a time.",
150
+        "alreadySharedVideoMsg": "Another participant is already sharing a video. This conference allows only one shared video at a time.",
152
         "alreadySharedVideoTitle": "Only one shared video is allowed at a time",
151
         "alreadySharedVideoTitle": "Only one shared video is allowed at a time",
153
         "applicationWindow": "Application window",
152
         "applicationWindow": "Application window",
154
         "Back": "Back",
153
         "Back": "Back",
173
         "connecting": "Connecting",
172
         "connecting": "Connecting",
174
         "contactSupport": "Contact support",
173
         "contactSupport": "Contact support",
175
         "copy": "Copy",
174
         "copy": "Copy",
176
-        "currentPassword": "The current password is",
177
         "defaultError": "There was some kind of error",
175
         "defaultError": "There was some kind of error",
178
         "detectext": "Error when trying to detect desktopsharing extension.",
176
         "detectext": "Error when trying to detect desktopsharing extension.",
179
         "dismiss": "Dismiss",
177
         "dismiss": "Dismiss",
200
         "kickMessage": "You can contact __participantDisplayName__ for more details.",
198
         "kickMessage": "You can contact __participantDisplayName__ for more details.",
201
         "kickParticipantButton": "Kick",
199
         "kickParticipantButton": "Kick",
202
         "kickParticipantDialog": "Are you sure you want to kick this participant?",
200
         "kickParticipantDialog": "Are you sure you want to kick this participant?",
203
-        "kickParticipantTitle": "Kick this member?",
201
+        "kickParticipantTitle": "Kick this participant?",
204
         "kickTitle": "Ouch! __participantDisplayName__ kicked you out of the meeting",
202
         "kickTitle": "Ouch! __participantDisplayName__ kicked you out of the meeting",
205
         "liveStreaming": "Live Streaming",
203
         "liveStreaming": "Live Streaming",
206
         "liveStreamingDisabledForGuestTooltip": "Guests can't start live streaming.",
204
         "liveStreamingDisabledForGuestTooltip": "Guests can't start live streaming.",
207
         "liveStreamingDisabledTooltip": "Start live stream disabled.",
205
         "liveStreamingDisabledTooltip": "Start live stream disabled.",
208
         "lockMessage": "Failed to lock the conference.",
206
         "lockMessage": "Failed to lock the conference.",
209
-        "lockRoom": "Add meeting password",
207
+        "lockRoom": "Add meeting $t(lockRoomPasswordUppercase)",
210
         "lockTitle": "Lock failed",
208
         "lockTitle": "Lock failed",
211
         "logoutQuestion": "Are you sure you want to logout and stop the conference?",
209
         "logoutQuestion": "Are you sure you want to logout and stop the conference?",
212
         "logoutTitle": "Logout",
210
         "logoutTitle": "Logout",
213
-        "maxUsersLimitReached": "The limit for maximum number of members has been reached. The conference is full. Please contact the meeting owner or try again later!",
214
-        "maxUsersLimitReachedTitle": "Maximum members limit reached",
211
+        "maxUsersLimitReached": "The limit for maximum number of participants has been reached. The conference is full. Please contact the meeting owner or try again later!",
212
+        "maxUsersLimitReachedTitle": "Maximum participants limit reached",
215
         "micConstraintFailedError": "Your microphone does not satisfy some of the required constraints.",
213
         "micConstraintFailedError": "Your microphone does not satisfy some of the required constraints.",
216
         "micNotFoundError": "Microphone was not found.",
214
         "micNotFoundError": "Microphone was not found.",
217
         "micNotSendingData": "Go to your computer's settings to unmute your mic and adjust its level",
215
         "micNotSendingData": "Go to your computer's settings to unmute your mic and adjust its level",
221
         "muteParticipantBody": "You won't be able to unmute them, but they can unmute themselves at any time.",
219
         "muteParticipantBody": "You won't be able to unmute them, but they can unmute themselves at any time.",
222
         "muteParticipantButton": "Mute",
220
         "muteParticipantButton": "Mute",
223
         "muteParticipantDialog": "Are you sure you want to mute this participant? You won't be able to unmute them, but they can unmute themselves at any time.",
221
         "muteParticipantDialog": "Are you sure you want to mute this participant? You won't be able to unmute them, but they can unmute themselves at any time.",
224
-        "muteParticipantTitle": "Mute this member?",
222
+        "muteParticipantTitle": "Mute this participant?",
225
         "Ok": "Ok",
223
         "Ok": "Ok",
226
         "oops": "Oops!",
224
         "oops": "Oops!",
227
-        "password": "Enter password",
228
-        "passwordError": "This conversation is currently protected by a password. Only the owner of the conference can set a password.",
229
-        "passwordError2": "This conversation isn't currently protected by a password. Only the owner of the conference can set a password.",
230
-        "passwordErrorTitle": "Password Error",
231
-        "passwordLabel": "Password",
232
-        "passwordNotSupported": "Setting a meeting password is not supported.",
233
-        "passwordNotSupportedTitle": "Password not supported",
234
-        "passwordRequired": "Password required",
225
+        "passwordLabel": "$t(lockRoomPasswordUppercase)",
226
+        "passwordNotSupported": "Setting a meeting $t(lockRoomPassword) is not supported.",
227
+        "passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) not supported",
228
+        "passwordRequired": "$t(lockRoomPasswordUppercase) required",
235
         "permissionDenied": "Permission Denied",
229
         "permissionDenied": "Permission Denied",
236
         "popupError": "Your browser is blocking pop-up windows from this site. Please enable pop-ups in your browser's security settings and try again.",
230
         "popupError": "Your browser is blocking pop-up windows from this site. Please enable pop-ups in your browser's security settings and try again.",
237
         "popupErrorTitle": "Pop-up blocked",
231
         "popupErrorTitle": "Pop-up blocked",
248
         "remoteControlStopMessage": "The remote control session ended!",
242
         "remoteControlStopMessage": "The remote control session ended!",
249
         "remoteControlTitle": "Remote desktop control",
243
         "remoteControlTitle": "Remote desktop control",
250
         "Remove": "Remove",
244
         "Remove": "Remove",
251
-        "removePassword": "Remove password",
245
+        "removePassword": "Remove $t(lockRoomPassword)",
252
         "removeSharedVideoMsg": "Are you sure you would like to remove your shared video?",
246
         "removeSharedVideoMsg": "Are you sure you would like to remove your shared video?",
253
         "removeSharedVideoTitle": "Remove shared video",
247
         "removeSharedVideoTitle": "Remove shared video",
254
         "reservationError": "Reservation system error",
248
         "reservationError": "Reservation system error",
286
         "tokenAuthFailedTitle": "Authentication failed",
280
         "tokenAuthFailedTitle": "Authentication failed",
287
         "transcribing": "Transcribing",
281
         "transcribing": "Transcribing",
288
         "unableToSwitch": "Unable to switch video stream.",
282
         "unableToSwitch": "Unable to switch video stream.",
289
-        "unlockRoom": "Remove meeting password",
283
+        "unlockRoom": "Remove meeting $t(lockRoomPassword)",
290
         "userPassword": "user password",
284
         "userPassword": "user password",
291
         "WaitForHostMsg": "The conference <b>__room__</b> has not yet started. If you are the host then please authenticate. Otherwise, please wait for the host to arrive.",
285
         "WaitForHostMsg": "The conference <b>__room__</b> has not yet started. If you are the host then please authenticate. Otherwise, please wait for the host to arrive.",
292
         "WaitForHostMsgWOk": "The conference <b>__room__</b> has not yet started. If you are the host then please press Ok to authenticate. Otherwise, please wait for the host to arrive.",
286
         "WaitForHostMsgWOk": "The conference <b>__room__</b> has not yet started. If you are the host then please press Ok to authenticate. Otherwise, please wait for the host to arrive.",
298
     "dialOut": {
292
     "dialOut": {
299
         "statusMessage": "is now __status__"
293
         "statusMessage": "is now __status__"
300
     },
294
     },
301
-    "email": {
302
-        "and": "and",
303
-        "body": [
304
-            " Note that __appName__ is currently only supported by __supportedBrowsers__, so you need to be using one of these browsers.",
305
-            "",
306
-            "",
307
-            "",
308
-            "",
309
-            "",
310
-            "",
311
-            "",
312
-            "",
313
-            "Hey there, I%27d like to invite you to a __appName__ conference I%27ve just set up.",
314
-            "Please click on the following link in order to join the conference.",
315
-            "Talk to you in a sec!",
316
-            "__roomUrl__",
317
-            "__sharedKeyText__"
318
-        ],
319
-        "sharedKey": [
320
-            "",
321
-            "",
322
-            "",
323
-            "",
324
-            "This conference is password-protected. Please use the following pin when joining:",
325
-            "__sharedKey__"
326
-        ],
327
-        "subject": "Invitation to a __appName__ (__conferenceName__)"
328
-    },
329
     "feedback": {
295
     "feedback": {
330
         "average": "Average",
296
         "average": "Average",
331
         "bad": "Bad",
297
         "bad": "Bad",
344
     },
310
     },
345
     "info": {
311
     "info": {
346
         "accessibilityLabel": "Show info",
312
         "accessibilityLabel": "Show info",
347
-        "addPassword": "Add password",
348
-        "cancelPassword": "Cancel password",
313
+        "addPassword": "Add $t(lockRoomPassword)",
314
+        "cancelPassword": "Cancel $t(lockRoomPassword)",
349
         "conferenceURL": "Link:",
315
         "conferenceURL": "Link:",
350
         "country": "Country",
316
         "country": "Country",
351
         "dialANumber": "To join your meeting, dial one of these numbers and then enter the pin.",
317
         "dialANumber": "To join your meeting, dial one of these numbers and then enter the pin.",
367
         "noPassword": "None",
333
         "noPassword": "None",
368
         "noRoom": "No room was specified to dial-in into.",
334
         "noRoom": "No room was specified to dial-in into.",
369
         "numbers": "Dial-in Numbers",
335
         "numbers": "Dial-in Numbers",
370
-        "password": "Password:",
336
+        "password": "$t(lockRoomPasswordUppercase):",
371
         "title": "Share",
337
         "title": "Share",
372
         "tooltip": "Share link and dial-in info for this meeting",
338
         "tooltip": "Share link and dial-in info for this meeting",
373
         "label": "Meeting info"
339
         "label": "Meeting info"
463
         "stop": "Stop Recording",
429
         "stop": "Stop Recording",
464
         "yes": "Yes"
430
         "yes": "Yes"
465
     },
431
     },
432
+    "lockRoomPassword": "password",
433
+    "lockRoomPasswordUppercase": "Password",
466
     "me": "me",
434
     "me": "me",
467
     "notify": {
435
     "notify": {
468
         "connectedOneMember": "__name__ joined the meeting",
436
         "connectedOneMember": "__name__ joined the meeting",
482
         "mutedTitle": "You're muted!",
450
         "mutedTitle": "You're muted!",
483
         "mutedRemotelyTitle": "You have been muted by __participantDisplayName__!",
451
         "mutedRemotelyTitle": "You have been muted by __participantDisplayName__!",
484
         "mutedRemotelyDescription": "You can always unmute when you're ready to speak. Mute back when you're done to keep noise away from the meeting.",
452
         "mutedRemotelyDescription": "You can always unmute when you're ready to speak. Mute back when you're done to keep noise away from the meeting.",
453
+        "passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removed by another participant",
454
+        "passwordSetRemotely": "$t(lockRoomPasswordUppercase) set by another participant",
485
         "raisedHand": "__name__ would like to speak.",
455
         "raisedHand": "__name__ would like to speak.",
486
         "somebody": "Somebody",
456
         "somebody": "Somebody",
487
         "startSilentTitle": "You joined with no audio output!",
457
         "startSilentTitle": "You joined with no audio output!",
493
         "newDeviceAudioTitle": "New audio device detected",
463
         "newDeviceAudioTitle": "New audio device detected",
494
         "newDeviceAction": "Use"
464
         "newDeviceAction": "Use"
495
     },
465
     },
496
-    "passwordSetRemotely": "set by another member",
466
+    "passwordSetRemotely": "set by another participant",
497
     "passwordDigitsOnly": "Up to __number__ digits",
467
     "passwordDigitsOnly": "Up to __number__ digits",
498
     "poweredby": "powered by",
468
     "poweredby": "powered by",
499
     "presenceStatus": {
469
     "presenceStatus": {
568
         "more": "More",
538
         "more": "More",
569
         "name": "Name",
539
         "name": "Name",
570
         "noDevice": "None",
540
         "noDevice": "None",
571
-        "password": "SET PASSWORD",
572
         "selectAudioOutput": "Audio output",
541
         "selectAudioOutput": "Audio output",
573
         "selectCamera": "Camera",
542
         "selectCamera": "Camera",
574
         "selectMic": "Microphone",
543
         "selectMic": "Microphone",
685
         "raiseYourHand": "Raise your hand",
654
         "raiseYourHand": "Raise your hand",
686
         "Settings": "Settings",
655
         "Settings": "Settings",
687
         "sharedvideo": "Share a YouTube video",
656
         "sharedvideo": "Share a YouTube video",
688
-        "sharedVideoMutedPopup": "Your shared video has been muted so that you can talk to the other members.",
657
+        "sharedVideoMutedPopup": "Your shared video has been muted so that you can talk to the other participants.",
689
         "shareRoom": "Invite someone",
658
         "shareRoom": "Invite someone",
690
         "shortcuts": "View shortcuts",
659
         "shortcuts": "View shortcuts",
691
         "sip": "Call SIP number",
660
         "sip": "Call SIP number",
765
         "flip": "Flip",
734
         "flip": "Flip",
766
         "kick": "Kick out",
735
         "kick": "Kick out",
767
         "moderator": "Moderator",
736
         "moderator": "Moderator",
768
-        "mute": "Member is muted",
737
+        "mute": "Participant is muted",
769
         "muted": "Muted",
738
         "muted": "Muted",
770
         "remoteControl": "Remote control",
739
         "remoteControl": "Remote control",
771
         "show": "Show on stage",
740
         "show": "Show on stage",
772
-        "videomute": "Member has stopped the camera"
741
+        "videomute": "Participant has stopped the camera"
773
     },
742
     },
774
     "welcomepage": {
743
     "welcomepage": {
775
         "accessibilityLabel": {
744
         "accessibilityLabel": {

+ 28
- 0
react/features/invite/_utils.js Просмотреть файл

1
+// @flow
2
+
3
+/**
4
+ * Utility class with no dependencies. Used in components that are stripped in separate bundles
5
+ * and requires as less dependencies as possible.
6
+ */
7
+
8
+/**
9
+ * Formats the conference pin in readable way for UI to display it.
10
+ * Formats the pin in 3 groups of digits:
11
+ * XXXX XXXX XX or XXXXX XXXXX XXX.
12
+ * The length of first and second group is Math.ceil(pin.length / 3)
13
+ *
14
+ * @param {Object} conferenceID - The conference id to format, string or number.
15
+ * @returns {string} - The formatted conference pin.
16
+ * @private
17
+ */
18
+export function _formatConferenceIDPin(conferenceID: Object) {
19
+    const conferenceIDStr = conferenceID.toString();
20
+
21
+    // let's split the conferenceID in 3 parts, to be easier to read
22
+    const partLen = Math.ceil(conferenceIDStr.length / 3);
23
+
24
+    return `${
25
+        conferenceIDStr.substring(0, partLen)} ${
26
+        conferenceIDStr.substring(partLen, 2 * partLen)} ${
27
+        conferenceIDStr.substring(2 * partLen, conferenceIDStr.length)}`;
28
+}

+ 3
- 1
react/features/invite/components/dial-in-summary/web/ConferenceID.js Просмотреть файл

4
 
4
 
5
 import { translate } from '../../../../base/i18n';
5
 import { translate } from '../../../../base/i18n';
6
 
6
 
7
+import { _formatConferenceIDPin } from '../../../_utils';
8
+
7
 /**
9
 /**
8
  * The type of the React {@code Component} props of {@link ConferenceID}.
10
  * The type of the React {@code Component} props of {@link ConferenceID}.
9
  */
11
  */
49
                     { t('info.dialANumber') }
51
                     { t('info.dialANumber') }
50
                 </div>
52
                 </div>
51
                 <div className = 'dial-in-conference-pin'>
53
                 <div className = 'dial-in-conference-pin'>
52
-                    { `${t('info.dialInConferenceID')} ${conferenceID}` }
54
+                    { `${t('info.dialInConferenceID')} ${_formatConferenceIDPin(conferenceID)}` }
53
                 </div>
55
                 </div>
54
             </div>
56
             </div>
55
         );
57
         );

+ 3
- 1
react/features/invite/components/info-dialog/web/DialInNumber.js Просмотреть файл

4
 
4
 
5
 import { translate } from '../../../../base/i18n';
5
 import { translate } from '../../../../base/i18n';
6
 
6
 
7
+import { _formatConferenceIDPin } from '../../../_utils';
8
+
7
 /**
9
 /**
8
  * The type of the React {@code Component} props of {@link DialInNumber}.
10
  * The type of the React {@code Component} props of {@link DialInNumber}.
9
  */
11
  */
61
                     </span>
63
                     </span>
62
                     <span className = 'spacer'>&nbsp;</span>
64
                     <span className = 'spacer'>&nbsp;</span>
63
                     <span className = 'info-value'>
65
                     <span className = 'info-value'>
64
-                        { `${conferenceID}#` }
66
+                        { `${_formatConferenceIDPin(conferenceID)}#` }
65
                     </span>
67
                     </span>
66
                 </span>
68
                 </span>
67
             </div>
69
             </div>

+ 26
- 2
react/features/room-lock/middleware.js Просмотреть файл

8
 import { hideDialog } from '../base/dialog';
8
 import { hideDialog } from '../base/dialog';
9
 import { JitsiConferenceErrors } from '../base/lib-jitsi-meet';
9
 import { JitsiConferenceErrors } from '../base/lib-jitsi-meet';
10
 import { MiddlewareRegistry } from '../base/redux';
10
 import { MiddlewareRegistry } from '../base/redux';
11
+import {
12
+    NOTIFICATION_TIMEOUT,
13
+    showNotification
14
+} from '../notifications';
11
 import UIEvents from '../../../service/UI/UIEvents';
15
 import UIEvents from '../../../service/UI/UIEvents';
12
 
16
 
13
 import { _openPasswordRequiredPrompt } from './actions';
17
 import { _openPasswordRequiredPrompt } from './actions';
14
 import { PasswordRequiredPrompt, RoomLockPrompt } from './components';
18
 import { PasswordRequiredPrompt, RoomLockPrompt } from './components';
19
+import { LOCKED_REMOTELY } from './constants';
15
 
20
 
16
 declare var APP: Object;
21
 declare var APP: Object;
17
 
22
 
29
     case CONFERENCE_FAILED:
34
     case CONFERENCE_FAILED:
30
         return _conferenceFailed(store, next, action);
35
         return _conferenceFailed(store, next, action);
31
 
36
 
32
-    case LOCK_STATE_CHANGED:
37
+    case LOCK_STATE_CHANGED: {
33
         // TODO Remove this logic when all components interested in the lock
38
         // TODO Remove this logic when all components interested in the lock
34
         // state change event are moved into react/redux.
39
         // state change event are moved into react/redux.
35
         if (typeof APP !== 'undefined') {
40
         if (typeof APP !== 'undefined') {
36
             APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK, action.locked);
41
             APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK, action.locked);
37
         }
42
         }
38
-        break;
39
 
43
 
44
+        const previousLockedState = store.getState()['features/base/conference'].locked;
45
+
46
+        const result = next(action);
47
+
48
+        const currentLockedState = store.getState()['features/base/conference'].locked;
49
+
50
+        if (currentLockedState === LOCKED_REMOTELY) {
51
+            store.dispatch(
52
+                showNotification({
53
+                    titleKey: 'notify.passwordSetRemotely'
54
+                }, NOTIFICATION_TIMEOUT));
55
+        } else if (previousLockedState === LOCKED_REMOTELY && !currentLockedState) {
56
+            store.dispatch(
57
+                showNotification({
58
+                    titleKey: 'notify.passwordRemovedRemotely'
59
+                }, NOTIFICATION_TIMEOUT));
60
+        }
61
+
62
+        return result;
63
+    }
40
     case SET_PASSWORD_FAILED:
64
     case SET_PASSWORD_FAILED:
41
         return _setPasswordFailed(store, next, action);
65
         return _setPasswordFailed(store, next, action);
42
     }
66
     }

Загрузка…
Отмена
Сохранить