Browse Source

fix(lobby): Inconsistent state after deny and then approve. (#15226)

* fix(lobby): Inconsistent state after deny and then approve.

Fixes several issues:
- The error on lobby deny is not sticky
- When preJoin is not enabled we were showing conference UI and showing the error, while the participant is denied to enter the meeting.
- There was inconsistent state (after deny we were keeping membersOnly conference state) and when being approved on re-try while being in the meeting, no remote thumbnails are shown although media is flowing.

The scenario is enabling lobby and tryintg to join, denying the first attempt and approving the second one.

* squash: Drop extra hide lobby screen.

* squash: Finish action first before showing the notification.
factor2
Дамян Минков 11 months ago
parent
commit
1a3dd699b7
No account linked to committer's email address

+ 14
- 0
react/features/base/conference/reducer.ts View File

@@ -167,6 +167,7 @@ export interface IConferenceState {
167 167
     followMeRecorderEnabled?: boolean;
168 168
     joining?: IJitsiConference;
169 169
     leaving?: IJitsiConference;
170
+    lobbyError?: boolean;
170 171
     lobbyWaitingForHost?: boolean;
171 172
     localSubject?: string;
172 173
     locked?: string;
@@ -369,13 +370,24 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: {
369 370
     let membersOnly;
370 371
     let passwordRequired;
371 372
     let lobbyWaitingForHost;
373
+    let lobbyError;
372 374
 
373 375
     switch (error.name) {
374 376
     case JitsiConferenceErrors.AUTHENTICATION_REQUIRED:
375 377
         authRequired = conference;
376 378
         break;
377 379
 
380
+    /**
381
+     * Access denied while waiting in the lobby.
382
+     * A conference error when we tried to join into a room with no display name when lobby is enabled in the room.
383
+     */
378 384
     case JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED:
385
+    case JitsiConferenceErrors.DISPLAY_NAME_REQUIRED: {
386
+        lobbyError = true;
387
+
388
+        break;
389
+    }
390
+
379 391
     case JitsiConferenceErrors.MEMBERS_ONLY_ERROR: {
380 392
         membersOnly = conference;
381 393
 
@@ -399,6 +411,7 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: {
399 411
         error,
400 412
         joining: undefined,
401 413
         leaving: undefined,
414
+        lobbyError,
402 415
         lobbyWaitingForHost,
403 416
 
404 417
         /**
@@ -456,6 +469,7 @@ function _conferenceJoined(state: IConferenceState, { conference }: { conference
456 469
         membersOnly: undefined,
457 470
         leaving: undefined,
458 471
 
472
+        lobbyError: undefined,
459 473
         lobbyWaitingForHost: undefined,
460 474
 
461 475
         /**

+ 2
- 0
react/features/lobby/actions.any.ts View File

@@ -209,6 +209,8 @@ export function startKnocking() {
209 209
         logger.info(`Lobby starting knocking (membersOnly = ${membersOnly})`);
210 210
 
211 211
         if (!membersOnly) {
212
+            // let's hide the notification (the case with denied access and retrying)
213
+            dispatch(hideNotification(LOBBY_NOTIFICATION_ID));
212 214
 
213 215
             // no membersOnly, this means we got lobby screen shown as someone
214 216
             // tried to join a conference that has lobby enabled without setting display name

+ 25
- 6
react/features/lobby/middleware.ts View File

@@ -43,6 +43,7 @@ import {
43 43
 import { INotificationProps } from '../notifications/types';
44 44
 import { open as openParticipantsPane } from '../participants-pane/actions';
45 45
 import { getParticipantsPaneOpen } from '../participants-pane/functions';
46
+import { PREJOIN_JOINING_IN_PROGRESS } from '../prejoin/actionTypes';
46 47
 import {
47 48
     isPrejoinEnabledInConfig,
48 49
     isPrejoinPageVisible,
@@ -108,6 +109,14 @@ MiddlewareRegistry.register(store => next => action => {
108 109
 
109 110
         return result;
110 111
     }
112
+    case PREJOIN_JOINING_IN_PROGRESS: {
113
+        if (action.value) {
114
+            // let's hide the notification (the case with denied access and retrying) when prejoin is enabled
115
+            store.dispatch(hideNotification(LOBBY_NOTIFICATION_ID));
116
+        }
117
+
118
+        break;
119
+    }
111 120
     }
112 121
 
113 122
     return next(action);
@@ -270,9 +279,8 @@ function _handleLobbyNotification(store: IStore) {
270 279
 function _conferenceFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
271 280
     const { error } = action;
272 281
     const state = getState();
273
-    const { membersOnly } = state['features/base/conference'];
282
+    const { lobbyError, membersOnly } = state['features/base/conference'];
274 283
     const nonFirstFailure = Boolean(membersOnly);
275
-    const { isDisplayNameRequiredError } = state['features/lobby'];
276 284
 
277 285
     if (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR) {
278 286
         if (typeof error.recoverable === 'undefined') {
@@ -288,7 +296,7 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio
288 296
 
289 297
         // if there was an error about display name and pre-join is not enabled
290 298
         if (shouldAutoKnock(state)
291
-                || (isDisplayNameRequiredError && !isPrejoinEnabledInConfig(state))
299
+                || (lobbyError && !isPrejoinEnabledInConfig(state))
292 300
                 || lobbyWaitingForHost) {
293 301
             dispatch(startKnocking());
294 302
         }
@@ -315,7 +323,17 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio
315 323
         return result;
316 324
     }
317 325
 
318
-    dispatch(hideLobbyScreen());
326
+    // if both are available pre-join is with priority (the case when pre-join is enabled)
327
+    // when pre-join is disabled, and we are in lobby with error, we want to end up in lobby UI
328
+    // instead of hiding it and showing conference UI. Still in lobby the user can retry
329
+    // after we show the error notification
330
+    if (isPrejoinPageVisible(state)) {
331
+        dispatch(hideLobbyScreen());
332
+    }
333
+
334
+    // we want to finish this action before showing the notification
335
+    // as the conference will be cleared which will clear all notifications, including this one
336
+    const result = next(action);
319 337
 
320 338
     if (error.name === JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED) {
321 339
         dispatch(
@@ -323,12 +341,13 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio
323 341
                 appearance: NOTIFICATION_TYPE.ERROR,
324 342
                 hideErrorSupportLink: true,
325 343
                 titleKey: 'lobby.joinRejectedTitle',
344
+                uid: LOBBY_NOTIFICATION_ID,
326 345
                 descriptionKey: 'lobby.joinRejectedMessage'
327
-            }, NOTIFICATION_TIMEOUT_TYPE.LONG)
346
+            }, NOTIFICATION_TIMEOUT_TYPE.STICKY)
328 347
         );
329 348
     }
330 349
 
331
-    return next(action);
350
+    return result;
332 351
 }
333 352
 
334 353
 /**

+ 1
- 0
react/features/lobby/reducer.ts View File

@@ -69,6 +69,7 @@ ReducerRegistry.register<ILobbyState>('features/lobby', (state = DEFAULT_STATE,
69 69
     case CONFERENCE_LEFT:
70 70
         return {
71 71
             ...state,
72
+            isDisplayNameRequiredError: false,
72 73
             knocking: false,
73 74
             passwordJoinFailed: false
74 75
         };

Loading…
Cancel
Save