diff --git a/package-lock.json b/package-lock.json index 95b61bd541e9..decddf70bd43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "js-md5": "0.6.1", "js-sha512": "0.8.0", "jwt-decode": "2.2.0", - "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1680.0.0+b760f4e1/lib-jitsi-meet.tgz", + "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1681.0.0+6cd397fa/lib-jitsi-meet.tgz", "lodash": "4.17.21", "moment": "2.29.4", "moment-duration-format": "2.2.2", @@ -12777,8 +12777,8 @@ }, "node_modules/lib-jitsi-meet": { "version": "0.0.0", - "resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1680.0.0+b760f4e1/lib-jitsi-meet.tgz", - "integrity": "sha512-UnYEUl8Hx7FSEQaSFOelC4stn0UW0jvllQelfvO5OVnkfelgRnkAQ9qB0Na7bPLLy+P9BIgWWGWDacWwRL3dDQ==", + "resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1681.0.0+6cd397fa/lib-jitsi-meet.tgz", + "integrity": "sha512-IUjwOod8/HX785klIwINfmnxjrE4iwaMZCEmng9SQoCdAtZDqo8XsAI0+pLyBpttJ/fhUkBI/ox8Vw2Ic4TB9w==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -12804,21 +12804,6 @@ "webrtc-adapter": "8.1.1" } }, - "node_modules/lib-jitsi-meet/node_modules/@jitsi/js-utils": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.1.3.tgz", - "integrity": "sha512-fXoNLu2JHQGPgzjCDG5qWPPStiXI+AxSzu1JIVY4dMULIFsw4a+doMgcjTIlSfB393J2xccKQYwZSejZUn9MEw==", - "dependencies": { - "@hapi/bourne": "^3.0.0", - "bowser": "2.7.0", - "js-md5": "0.7.3" - } - }, - "node_modules/lib-jitsi-meet/node_modules/@jitsi/logger": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@jitsi/logger/-/logger-2.0.2.tgz", - "integrity": "sha512-qwbpRwuwkBFgh0F5jivq/5fAm46yVoXURc5LCklEs8lAShYVangFEXKW7RLpZuZ5nQnrHrlvU8MswQNREmvahg==" - }, "node_modules/lib-jitsi-meet/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -12901,11 +12886,6 @@ "node": ">=8" } }, - "node_modules/lib-jitsi-meet/node_modules/js-md5": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", - "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==" - }, "node_modules/lib-jitsi-meet/node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -29311,8 +29291,8 @@ } }, "lib-jitsi-meet": { - "version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1680.0.0+b760f4e1/lib-jitsi-meet.tgz", - "integrity": "sha512-UnYEUl8Hx7FSEQaSFOelC4stn0UW0jvllQelfvO5OVnkfelgRnkAQ9qB0Na7bPLLy+P9BIgWWGWDacWwRL3dDQ==", + "version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1681.0.0+6cd397fa/lib-jitsi-meet.tgz", + "integrity": "sha512-IUjwOod8/HX785klIwINfmnxjrE4iwaMZCEmng9SQoCdAtZDqo8XsAI0+pLyBpttJ/fhUkBI/ox8Vw2Ic4TB9w==", "requires": { "@jitsi/js-utils": "2.1.3", "@jitsi/logger": "2.0.2", @@ -29336,21 +29316,6 @@ "webrtc-adapter": "8.1.1" }, "dependencies": { - "@jitsi/js-utils": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.1.3.tgz", - "integrity": "sha512-fXoNLu2JHQGPgzjCDG5qWPPStiXI+AxSzu1JIVY4dMULIFsw4a+doMgcjTIlSfB393J2xccKQYwZSejZUn9MEw==", - "requires": { - "@hapi/bourne": "^3.0.0", - "bowser": "2.7.0", - "js-md5": "0.7.3" - } - }, - "@jitsi/logger": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@jitsi/logger/-/logger-2.0.2.tgz", - "integrity": "sha512-qwbpRwuwkBFgh0F5jivq/5fAm46yVoXURc5LCklEs8lAShYVangFEXKW7RLpZuZ5nQnrHrlvU8MswQNREmvahg==" - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -29409,11 +29374,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "js-md5": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", - "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==" - }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", diff --git a/package.json b/package.json index 781842070f6a..dab36a13220b 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "js-md5": "0.6.1", "js-sha512": "0.8.0", "jwt-decode": "2.2.0", - "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1680.0.0+b760f4e1/lib-jitsi-meet.tgz", + "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1681.0.0+6cd397fa/lib-jitsi-meet.tgz", "lodash": "4.17.21", "moment": "2.29.4", "moment-duration-format": "2.2.2", diff --git a/react/features/base/conference/actions.ts b/react/features/base/conference/actions.ts index 2679e6b00850..ce7b2a706d31 100644 --- a/react/features/base/conference/actions.ts +++ b/react/features/base/conference/actions.ts @@ -2,9 +2,11 @@ import { createStartMutedConfigurationEvent } from '../../analytics/AnalyticsEve import { sendAnalytics } from '../../analytics/functions'; import { IReduxState, IStore } from '../../app/types'; import { endpointMessageReceived } from '../../subtitles/actions.any'; +import { setIAmVisitor } from '../../visitors/actions'; import { iAmVisitor } from '../../visitors/functions'; +import { overwriteConfig } from '../config/actions'; import { getReplaceParticipant } from '../config/functions'; -import { hangup } from '../connection/actions'; +import { connect, disconnect, hangup } from '../connection/actions'; import { JITSI_CONNECTION_CONFERENCE_KEY } from '../connection/constants'; import { JitsiConferenceEvents, JitsiE2ePingEvents } from '../lib-jitsi-meet'; import { setAudioMuted, setAudioUnmutePermissions, setVideoMuted, setVideoUnmutePermissions } from '../media/actions'; @@ -73,6 +75,7 @@ import { getConferenceOptions, getConferenceState, getCurrentConference, + getVisitorOptions, sendLocalParticipant } from './functions'; import logger from './logger'; @@ -983,3 +986,41 @@ export function setAssumedBandwidthBps(assumedBandwidthBps: number) { assumedBandwidthBps }; } + +/** + * Redirects to a new visitor node. + * + * @param {string | undefined} vnode - The vnode to use or undefined if moving back to the main room. + * @param {string} focusJid - The focus jid to use. + * @param {string} username - The username to use. + * @returns {void} + */ +export function redirect(vnode: string, focusJid: string, username: string) { + return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { + const { conference, joining } = getState()['features/base/conference']; + + const newConfig = getVisitorOptions(getState, vnode, focusJid, username); + + if (!newConfig) { + logger.warn('Not redirected missing params'); + + return; + } + + dispatch(overwriteConfig(newConfig)) // @ts-ignore + .then(() => dispatch(conferenceWillLeave(conference || joining))) + .then(() => dispatch(disconnect())) + .then(() => dispatch(setIAmVisitor(Boolean(vnode)))) + + // we do not clear local tracks on error, so we need to manually clear them + .then(() => dispatch(destroyLocalTracks())) + .then(() => dispatch(conferenceWillInit())) + .then(() => dispatch(connect())) + .then(() => { + // FIXME: Workaround for the web version. To be removed once we get rid of conference.js + if (typeof APP !== 'undefined') { + APP.conference.startConference([]); + } + }); + }; +} diff --git a/react/features/base/conference/functions.ts b/react/features/base/conference/functions.ts index b981e27161ab..ed5aa826b8eb 100644 --- a/react/features/base/conference/functions.ts +++ b/react/features/base/conference/functions.ts @@ -284,12 +284,12 @@ export function restoreConferenceOptions(stateful: IStateful) { * Override the global config (that is, window.config) with XMPP configuration required to join as a visitor. * * @param {IStateful} stateful - The redux store state. - * @param {Array} params - The received parameters. + * @param {string|undefined} vnode - The received parameters. + * @param {string} focusJid - The received parameters. + * @param {string|undefined} username - The received parameters. * @returns {Object} */ -export function getVisitorOptions(stateful: IStateful, params: Array) { - const [ vnode, focusJid, username ] = params; - +export function getVisitorOptions(stateful: IStateful, vnode: string, focusJid: string, username: string) { const config = toState(stateful)['features/base/config']; if (!config?.hosts) { diff --git a/react/features/base/conference/middleware.any.ts b/react/features/base/conference/middleware.any.ts index 5d347ec0759a..d1f0aea6b68b 100644 --- a/react/features/base/conference/middleware.any.ts +++ b/react/features/base/conference/middleware.any.ts @@ -18,7 +18,6 @@ import { showErrorNotification } from '../../notifications/actions'; import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants'; import { stopLocalVideoRecording } from '../../recording/actions.any'; import LocalRecordingManager from '../../recording/components/Recording/LocalRecordingManager'; -import { setIAmVisitor } from '../../visitors/actions'; import { iAmVisitor } from '../../visitors/functions'; import { overwriteConfig } from '../config/actions'; import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../connection/actionTypes'; @@ -34,7 +33,6 @@ import { } from '../participants/functions'; import MiddlewareRegistry from '../redux/MiddlewareRegistry'; import { TRACK_ADDED, TRACK_REMOVED } from '../tracks/actionTypes'; -import { destroyLocalTracks } from '../tracks/actions.any'; import { getLocalTracks } from '../tracks/functions.any'; import { @@ -51,7 +49,6 @@ import { import { authStatusChanged, conferenceFailed, - conferenceWillInit, conferenceWillLeave, createConference, setLocalSubject, @@ -63,7 +60,6 @@ import { _removeLocalTracksFromConference, forEachConference, getCurrentConference, - getVisitorOptions, restoreConferenceOptions } from './functions'; import logger from './logger'; @@ -202,34 +198,6 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio case JitsiConferenceErrors.OFFER_ANSWER_FAILED: sendAnalytics(createOfferAnswerFailedEvent()); break; - - case JitsiConferenceErrors.REDIRECTED: { - const newConfig = getVisitorOptions(getState, error.params); - - if (!newConfig) { - logger.warn('Not redirected missing params'); - break; - } - - const [ vnode ] = error.params; - - dispatch(overwriteConfig(newConfig)) // @ts-ignore - .then(() => dispatch(conferenceWillLeave(conference))) - .then(() => dispatch(disconnect())) - .then(() => dispatch(setIAmVisitor(Boolean(vnode)))) - - // we do not clear local tracks on error, so we need to manually clear them - .then(() => dispatch(destroyLocalTracks())) - .then(() => dispatch(conferenceWillInit())) - .then(() => dispatch(connect())) - .then(() => { - // FIXME: Workaround for the web version. To be removed once we get rid of conference.js - if (typeof APP !== 'undefined') { - APP.conference.startConference([]); - } - }); - break; - } } !error.recoverable diff --git a/react/features/base/connection/actions.any.ts b/react/features/base/connection/actions.any.ts index 07121bef2900..49e4fcc13df4 100644 --- a/react/features/base/connection/actions.any.ts +++ b/react/features/base/connection/actions.any.ts @@ -1,7 +1,7 @@ import _ from 'lodash'; import { IReduxState, IStore } from '../../app/types'; -import { conferenceLeft, conferenceWillLeave } from '../conference/actions'; +import { conferenceLeft, conferenceWillLeave, redirect } from '../conference/actions'; import { getCurrentConference } from '../conference/functions'; import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet'; import { @@ -230,6 +230,9 @@ export function _connectInternal(id?: string, password?: string) { connection.addEventListener( JitsiConnectionEvents.CONNECTION_FAILED, _onConnectionFailed); + connection.addEventListener( + JitsiConnectionEvents.CONNECTION_REDIRECTED, + _onConnectionRedirected); /** * Unsubscribe the connection instance from @@ -298,9 +301,28 @@ export function _connectInternal(id?: string, password?: string) { resolve(connection); } + /** + * Rejects external promise when connection fails. + * + * @param {string|undefined} vnode - The vnode to connect to. + * @param {string} focusJid - The focus jid to use. + * @param {string|undefined} username - The username to use when joining. This is after promotion from + * visitor to main participant. + * @private + * @returns {void} + */ + function _onConnectionRedirected(vnode: string, focusJid: string, username: string) { + connection.removeEventListener(JitsiConnectionEvents.CONNECTION_REDIRECTED, _onConnectionRedirected); + dispatch(redirect(vnode, focusJid, username)); + } + + // in case of configured http url for conference request we need the room name + const name = getBackendSafeRoomName(state['features/base/conference'].room); + connection.connect({ id, - password + password, + name }); }); };