Bladeren bron

feat(replace-participant): Replace participant with same jwt in the conf

- update lib-jitsi-meet to version with support for replacing participant
master
hmuresan 4 jaren geleden
bovenliggende
commit
342dd4ceca

+ 22
- 3
conference.js Bestand weergeven

@@ -304,10 +304,14 @@ class ConferenceConnector {
304 304
 
305 305
         // not enough rights to create conference
306 306
         case JitsiConferenceErrors.AUTHENTICATION_REQUIRED: {
307
+            const { replaceParticipant }
308
+                = APP.store.getState()['features/base/config'];
309
+
310
+
307 311
             // Schedule reconnect to check if someone else created the room.
308 312
             this.reconnectTimeout = setTimeout(() => {
309 313
                 APP.store.dispatch(conferenceWillJoin(room));
310
-                room.join();
314
+                room.join(null, replaceParticipant);
311 315
             }, 5000);
312 316
 
313 317
             const { password }
@@ -393,8 +397,10 @@ class ConferenceConnector {
393 397
      *
394 398
      */
395 399
     connect() {
400
+        const { replaceParticipant } = APP.store.getState()['features/base/config'];
401
+
396 402
         // the local storage overrides here and in connection.js can be used by jibri
397
-        room.join(jitsiLocalStorage.getItem('xmpp_conference_password_override'));
403
+        room.join(jitsiLocalStorage.getItem('xmpp_conference_password_override'), replaceParticipant);
398 404
     }
399 405
 }
400 406
 
@@ -2167,7 +2173,20 @@ export default {
2167 2173
             JitsiConferenceEvents.LOCK_STATE_CHANGED,
2168 2174
             (...args) => APP.store.dispatch(lockStateChanged(room, ...args)));
2169 2175
 
2170
-        room.on(JitsiConferenceEvents.KICKED, participant => {
2176
+        room.on(JitsiConferenceEvents.KICKED, (participant, reason, isReplaced) => {
2177
+            if (isReplaced) {
2178
+                // this event triggers when the local participant is kicked, `participant`
2179
+                // is the kicker. In replace participant case, kicker is undefined,
2180
+                // as the server initiated it. We mark in store the local participant
2181
+                // as being replaced based on jwt.
2182
+                const localParticipant = getLocalParticipant(APP.store.getState());
2183
+
2184
+                APP.store.dispatch(participantUpdated({
2185
+                    conference: room,
2186
+                    id: localParticipant.id,
2187
+                    isReplaced
2188
+                }));
2189
+            }
2171 2190
             APP.store.dispatch(kickedOut(room, participant));
2172 2191
         });
2173 2192
 

+ 4
- 1
modules/UI/authentication/AuthHandler.js Bestand weergeven

@@ -209,7 +209,10 @@ function logout(room: Object) {
209 209
     }).then(url => {
210 210
         // de-authenticate conference on the fly
211 211
         if (room.isJoined()) {
212
-            room.join();
212
+            const { replaceParticipant }
213
+                = APP.store.getState()['features/base/config'];
214
+
215
+            room.join(null, replaceParticipant);
213 216
         }
214 217
 
215 218
         return url;

+ 2
- 2
package-lock.json Bestand weergeven

@@ -11071,8 +11071,8 @@
11071 11071
       }
11072 11072
     },
11073 11073
     "lib-jitsi-meet": {
11074
-      "version": "github:jitsi/lib-jitsi-meet#2259d4418574841a782e98df27c44370bb84df45",
11075
-      "from": "github:jitsi/lib-jitsi-meet#2259d4418574841a782e98df27c44370bb84df45",
11074
+      "version": "github:jitsi/lib-jitsi-meet#fad985e95a9e8a4fb8a1b8b1ad2cfef75370c866",
11075
+      "from": "github:jitsi/lib-jitsi-meet#fad985e95a9e8a4fb8a1b8b1ad2cfef75370c866",
11076 11076
       "requires": {
11077 11077
         "@jitsi/js-utils": "1.0.2",
11078 11078
         "@jitsi/sdp-interop": "github:jitsi/sdp-interop#5fc4af6dcf8a6e6af9fedbcd654412fd47b1b4ae",

+ 1
- 1
package.json Bestand weergeven

@@ -55,7 +55,7 @@
55 55
     "jquery-i18next": "1.2.1",
56 56
     "js-md5": "0.6.1",
57 57
     "jwt-decode": "2.2.0",
58
-    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#2259d4418574841a782e98df27c44370bb84df45",
58
+    "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#fad985e95a9e8a4fb8a1b8b1ad2cfef75370c866",
59 59
     "libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
60 60
     "lodash": "4.17.21",
61 61
     "moment": "2.29.1",

+ 5
- 2
react/features/base/conference/actions.js Bestand weergeven

@@ -460,7 +460,7 @@ export function createConference() {
460 460
 
461 461
         sendLocalParticipant(state, conference);
462 462
 
463
-        conference.join(password);
463
+        conference.join(password, config.replaceParticipant);
464 464
     };
465 465
 }
466 466
 
@@ -477,8 +477,11 @@ export function checkIfCanJoin() {
477 477
         const { authRequired, password }
478 478
             = getState()['features/base/conference'];
479 479
 
480
+        const { replaceParticipant }
481
+            = getState()['features/base/config'];
482
+
480 483
         authRequired && dispatch(_conferenceWillJoin(authRequired));
481
-        authRequired && authRequired.join(password);
484
+        authRequired && authRequired.join(password, replaceParticipant);
482 485
     };
483 486
 }
484 487
 

+ 7
- 2
react/features/base/conference/functions.js Bestand weergeven

@@ -87,6 +87,8 @@ export function commonUserJoinedHandling(
87 87
     if (user.isHidden()) {
88 88
         dispatch(hiddenParticipantJoined(id, displayName));
89 89
     } else {
90
+        const isReplacing = user.isReplacing && user.isReplacing();
91
+
90 92
         dispatch(participantJoined({
91 93
             botType: user.getBotType(),
92 94
             connectionStatus: user.getConnectionStatus(),
@@ -94,7 +96,8 @@ export function commonUserJoinedHandling(
94 96
             id,
95 97
             name: displayName,
96 98
             presence: user.getStatus(),
97
-            role: user.getRole()
99
+            role: user.getRole(),
100
+            isReplacing
98 101
         }));
99 102
     }
100 103
 }
@@ -119,7 +122,9 @@ export function commonUserLeftHandling(
119 122
     if (user.isHidden()) {
120 123
         dispatch(hiddenParticipantLeft(id));
121 124
     } else {
122
-        dispatch(participantLeft(id, conference));
125
+        const isReplaced = user.isReplaced && user.isReplaced();
126
+
127
+        dispatch(participantLeft(id, conference, isReplaced));
123 128
     }
124 129
 }
125 130
 

+ 1
- 0
react/features/base/config/configWhitelist.js Bestand weergeven

@@ -152,6 +152,7 @@ export default [
152 152
     'requireDisplayName',
153 153
     'remoteVideoMenu',
154 154
     'roomPasswordNumberOfDigits',
155
+    'replaceParticipant',
155 156
     'resolution',
156 157
     'startAudioMuted',
157 158
     'startAudioOnly',

+ 9
- 3
react/features/base/participants/actions.js Bestand weergeven

@@ -366,6 +366,7 @@ export function hiddenParticipantLeft(id) {
366 366
  * with the participant identified by the specified {@code id}. Only the local
367 367
  * participant is allowed to not specify an associated {@code JitsiConference}
368 368
  * instance.
369
+ * @param {boolean} isReplaced - Whether the participant is to be replaced in the meeting.
369 370
  * @returns {{
370 371
  *     type: PARTICIPANT_LEFT,
371 372
  *     participant: {
@@ -374,12 +375,13 @@ export function hiddenParticipantLeft(id) {
374 375
  *     }
375 376
  * }}
376 377
  */
377
-export function participantLeft(id, conference) {
378
+export function participantLeft(id, conference, isReplaced) {
378 379
     return {
379 380
         type: PARTICIPANT_LEFT,
380 381
         participant: {
381 382
             conference,
382
-            id
383
+            id,
384
+            isReplaced
383 385
         }
384 386
     };
385 387
 }
@@ -490,9 +492,13 @@ export function participantKicked(kicker, kicked) {
490 492
         dispatch({
491 493
             type: PARTICIPANT_KICKED,
492 494
             kicked: kicked.getId(),
493
-            kicker: kicker.getId()
495
+            kicker: kicker?.getId()
494 496
         });
495 497
 
498
+        if (kicked.isReplaced && kicked.isReplaced()) {
499
+            return;
500
+        }
501
+
496 502
         dispatch(showNotification({
497 503
             titleArguments: {
498 504
                 kicked:

+ 5
- 3
react/features/base/participants/middleware.js Bestand weergeven

@@ -161,7 +161,7 @@ StateListenerRegistry.register(
161 161
         for (const p of getState()['features/base/participants']) {
162 162
             !p.local
163 163
                 && (!conference || p.conference !== conference)
164
-                && dispatch(participantLeft(p.id, p.conference));
164
+                && dispatch(participantLeft(p.id, p.conference, p.isReplaced));
165 165
         }
166 166
     });
167 167
 
@@ -356,14 +356,16 @@ function _maybePlaySounds({ getState, dispatch }, action) {
356 356
     if (!action.participant.local
357 357
             && (!startAudioMuted
358 358
                 || getParticipantCount(state) < startAudioMuted)) {
359
+        const { isReplacing, isReplaced } = action.participant;
360
+
359 361
         if (action.type === PARTICIPANT_JOINED) {
360 362
             const { presence } = action.participant;
361 363
 
362 364
             // The sounds for the poltergeist are handled by features/invite.
363
-            if (presence !== INVITED && presence !== CALLING) {
365
+            if (presence !== INVITED && presence !== CALLING && !isReplacing) {
364 366
                 dispatch(playSound(PARTICIPANT_JOINED_SOUND_ID));
365 367
             }
366
-        } else if (action.type === PARTICIPANT_LEFT) {
368
+        } else if (action.type === PARTICIPANT_LEFT && !isReplaced) {
367 369
             dispatch(playSound(PARTICIPANT_LEFT_SOUND_ID));
368 370
         }
369 371
     }

+ 2
- 0
react/features/base/participants/reducer.js Bestand weergeven

@@ -187,6 +187,7 @@ function _participantJoined({ participant }) {
187 187
         dominantSpeaker,
188 188
         email,
189 189
         isFakeParticipant,
190
+        isReplacing,
190 191
         isJigasi,
191 192
         loadableAvatarUrl,
192 193
         local,
@@ -218,6 +219,7 @@ function _participantJoined({ participant }) {
218 219
         email,
219 220
         id,
220 221
         isFakeParticipant,
222
+        isReplacing,
221 223
         isJigasi,
222 224
         loadableAvatarUrl,
223 225
         local: local || false,

+ 6
- 0
react/features/conference/actions.native.js Bestand weergeven

@@ -18,6 +18,12 @@ import { getParticipantDisplayName } from '../base/participants';
18 18
  */
19 19
 export function notifyKickedOut(participant: Object, submit: ?Function) {
20 20
     return (dispatch: Dispatch<any>, getState: Function) => {
21
+        if (!participant || (participant.isReplaced && participant.isReplaced())) {
22
+            submit && submit();
23
+
24
+            return;
25
+        }
26
+
21 27
         dispatch(openDialog(AlertDialog, {
22 28
             contentKey: {
23 29
                 key: 'dialog.kickTitle',

+ 4
- 0
react/features/conference/actions.web.js Bestand weergeven

@@ -18,6 +18,10 @@ import {
18 18
  */
19 19
 export function notifyKickedOut(participant: Object, _: ?Function) { // eslint-disable-line no-unused-vars
20 20
     return (dispatch: Dispatch<any>, getState: Function) => {
21
+        if (!participant || (participant.isReplaced && participant.isReplaced())) {
22
+            return;
23
+        }
24
+
21 25
         const args = {
22 26
             participantDisplayName:
23 27
                 getParticipantDisplayName(getState, participant.getId())

+ 1
- 1
react/features/external-api/middleware.js Bestand weergeven

@@ -113,7 +113,7 @@ MiddlewareRegistry.register(store => next => action => {
113 113
                 id: getLocalParticipant(store.getState()).id,
114 114
                 local: true
115 115
             },
116
-            { id: action.participant.getId() }
116
+            { id: action.participant ? action.participant.getId() : undefined }
117 117
         );
118 118
         break;
119 119
 

+ 2
- 1
react/features/lobby/components/AbstractKnockingParticipantList.js Bestand weergeven

@@ -71,6 +71,7 @@ export function mapStateToProps(state: Object): $Shape<Props> {
71 71
 
72 72
     return {
73 73
         _participants: knockingParticipants,
74
-        _visible: lobbyEnabled && isLocalParticipantModerator(state) && Boolean(knockingParticipants.length)
74
+        _visible: lobbyEnabled && isLocalParticipantModerator(state)
75
+          && Boolean(knockingParticipants && knockingParticipants.length)
75 76
     };
76 77
 }

+ 12
- 9
react/features/notifications/middleware.js Bestand weergeven

@@ -34,7 +34,7 @@ MiddlewareRegistry.register(store => next => action => {
34 34
         const { participant: p } = action;
35 35
         const { dispatch, getState } = store;
36 36
 
37
-        if (!p.local && !joinLeaveNotificationsDisabled()) {
37
+        if (!p.local && !joinLeaveNotificationsDisabled() && !p.isReplacing) {
38 38
             dispatch(showParticipantJoinedNotification(
39 39
                 getParticipantDisplayName(getState, p.id)
40 40
             ));
@@ -45,13 +45,15 @@ MiddlewareRegistry.register(store => next => action => {
45 45
             // Do not show the notification for mobile and also when the focus indicator is disabled.
46 46
             const displayName = getParticipantDisplayName(getState, p.id);
47 47
 
48
-            dispatch(showNotification({
49
-                descriptionArguments: { to: displayName || '$t(notify.somebody)' },
50
-                descriptionKey: 'notify.grantedTo',
51
-                titleKey: 'notify.somebody',
52
-                title: displayName
53
-            },
54
-            NOTIFICATION_TIMEOUT));
48
+            if (!p.isReplacing) {
49
+                dispatch(showNotification({
50
+                    descriptionArguments: { to: displayName || '$t(notify.somebody)' },
51
+                    descriptionKey: 'notify.grantedTo',
52
+                    titleKey: 'notify.somebody',
53
+                    title: displayName
54
+                },
55
+                NOTIFICATION_TIMEOUT));
56
+            }
55 57
         }
56 58
 
57 59
         return result;
@@ -65,7 +67,8 @@ MiddlewareRegistry.register(store => next => action => {
65 67
 
66 68
             if (typeof interfaceConfig === 'object'
67 69
                 && participant
68
-                && !participant.local) {
70
+                && !participant.local
71
+                && !action.participant.isReplaced) {
69 72
                 store.dispatch(showNotification({
70 73
                     descriptionKey: 'notify.disconnected',
71 74
                     titleKey: 'notify.somebody',

Laden…
Annuleren
Opslaan