diff --git a/react/features/base/conference/reducer.ts b/react/features/base/conference/reducer.ts index d081ee0a6cb5..349743be7087 100644 --- a/react/features/base/conference/reducer.ts +++ b/react/features/base/conference/reducer.ts @@ -167,6 +167,7 @@ export interface IConferenceState { followMeRecorderEnabled?: boolean; joining?: IJitsiConference; leaving?: IJitsiConference; + lobbyError?: boolean; lobbyWaitingForHost?: boolean; localSubject?: string; locked?: string; @@ -369,13 +370,24 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: { let membersOnly; let passwordRequired; let lobbyWaitingForHost; + let lobbyError; switch (error.name) { case JitsiConferenceErrors.AUTHENTICATION_REQUIRED: authRequired = conference; break; + /** + * Access denied while waiting in the lobby. + * A conference error when we tried to join into a room with no display name when lobby is enabled in the room. + */ case JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED: + case JitsiConferenceErrors.DISPLAY_NAME_REQUIRED: { + lobbyError = true; + + break; + } + case JitsiConferenceErrors.MEMBERS_ONLY_ERROR: { membersOnly = conference; @@ -399,6 +411,7 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: { error, joining: undefined, leaving: undefined, + lobbyError, lobbyWaitingForHost, /** @@ -456,6 +469,7 @@ function _conferenceJoined(state: IConferenceState, { conference }: { conference membersOnly: undefined, leaving: undefined, + lobbyError: undefined, lobbyWaitingForHost: undefined, /** diff --git a/react/features/lobby/actions.any.ts b/react/features/lobby/actions.any.ts index 19a38fa523c6..4e012dbf61ed 100644 --- a/react/features/lobby/actions.any.ts +++ b/react/features/lobby/actions.any.ts @@ -209,6 +209,8 @@ export function startKnocking() { logger.info(`Lobby starting knocking (membersOnly = ${membersOnly})`); if (!membersOnly) { + // let's hide the notification (the case with denied access and retrying) + dispatch(hideNotification(LOBBY_NOTIFICATION_ID)); // no membersOnly, this means we got lobby screen shown as someone // tried to join a conference that has lobby enabled without setting display name diff --git a/react/features/lobby/middleware.ts b/react/features/lobby/middleware.ts index 4488c0984227..bfca256a98fa 100644 --- a/react/features/lobby/middleware.ts +++ b/react/features/lobby/middleware.ts @@ -43,6 +43,7 @@ import { import { INotificationProps } from '../notifications/types'; import { open as openParticipantsPane } from '../participants-pane/actions'; import { getParticipantsPaneOpen } from '../participants-pane/functions'; +import { PREJOIN_JOINING_IN_PROGRESS } from '../prejoin/actionTypes'; import { isPrejoinEnabledInConfig, isPrejoinPageVisible, @@ -108,6 +109,14 @@ MiddlewareRegistry.register(store => next => action => { return result; } + case PREJOIN_JOINING_IN_PROGRESS: { + if (action.value) { + // let's hide the notification (the case with denied access and retrying) when prejoin is enabled + store.dispatch(hideNotification(LOBBY_NOTIFICATION_ID)); + } + + break; + } } return next(action); @@ -270,9 +279,8 @@ function _handleLobbyNotification(store: IStore) { function _conferenceFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) { const { error } = action; const state = getState(); - const { membersOnly } = state['features/base/conference']; + const { lobbyError, membersOnly } = state['features/base/conference']; const nonFirstFailure = Boolean(membersOnly); - const { isDisplayNameRequiredError } = state['features/lobby']; if (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR) { if (typeof error.recoverable === 'undefined') { @@ -288,7 +296,7 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio // if there was an error about display name and pre-join is not enabled if (shouldAutoKnock(state) - || (isDisplayNameRequiredError && !isPrejoinEnabledInConfig(state)) + || (lobbyError && !isPrejoinEnabledInConfig(state)) || lobbyWaitingForHost) { dispatch(startKnocking()); } @@ -315,7 +323,17 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio return result; } - dispatch(hideLobbyScreen()); + // if both are available pre-join is with priority (the case when pre-join is enabled) + // when pre-join is disabled, and we are in lobby with error, we want to end up in lobby UI + // instead of hiding it and showing conference UI. Still in lobby the user can retry + // after we show the error notification + if (isPrejoinPageVisible(state)) { + dispatch(hideLobbyScreen()); + } + + // we want to finish this action before showing the notification + // as the conference will be cleared which will clear all notifications, including this one + const result = next(action); if (error.name === JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED) { dispatch( @@ -323,12 +341,13 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio appearance: NOTIFICATION_TYPE.ERROR, hideErrorSupportLink: true, titleKey: 'lobby.joinRejectedTitle', + uid: LOBBY_NOTIFICATION_ID, descriptionKey: 'lobby.joinRejectedMessage' - }, NOTIFICATION_TIMEOUT_TYPE.LONG) + }, NOTIFICATION_TIMEOUT_TYPE.STICKY) ); } - return next(action); + return result; } /** diff --git a/react/features/lobby/reducer.ts b/react/features/lobby/reducer.ts index 5cd77910076f..4d79bf27c19e 100644 --- a/react/features/lobby/reducer.ts +++ b/react/features/lobby/reducer.ts @@ -69,6 +69,7 @@ ReducerRegistry.register('features/lobby', (state = DEFAULT_STATE, case CONFERENCE_LEFT: return { ...state, + isDisplayNameRequiredError: false, knocking: false, passwordJoinFailed: false };