From 7101f90b6e06761f828e68e4f00c67ff3a88c09e Mon Sep 17 00:00:00 2001 From: paweldomas Date: Mon, 6 May 2019 13:53:41 -0500 Subject: [PATCH] feat: add base/session --- connection.js | 6 +- react/features/app/actions.js | 17 +- react/features/authentication/actions.js | 1 + react/features/base/config/actions.js | 9 +- .../base/connection/actions.native.js | 76 +-------- react/features/base/connection/actions.web.js | 1 + react/features/base/session/Session.js | 86 ++++++++++ react/features/base/session/actionTypes.js | 8 + react/features/base/session/actions.js | 135 ++++++++++++++++ react/features/base/session/index.js | 6 + react/features/base/session/middleware.js | 148 ++++++++++++++++++ react/features/base/session/reducer.js | 27 ++++ react/features/base/session/selectors.js | 56 +++++++ .../components/native/Conference.js | 68 +------- 14 files changed, 501 insertions(+), 143 deletions(-) create mode 100644 react/features/base/session/Session.js create mode 100644 react/features/base/session/actionTypes.js create mode 100644 react/features/base/session/actions.js create mode 100644 react/features/base/session/index.js create mode 100644 react/features/base/session/middleware.js create mode 100644 react/features/base/session/reducer.js create mode 100644 react/features/base/session/selectors.js diff --git a/connection.js b/connection.js index fe725239d..030ebc008 100644 --- a/connection.js +++ b/connection.js @@ -5,7 +5,8 @@ import jitsiLocalStorage from './modules/util/JitsiLocalStorage'; import { connectionEstablished, - connectionFailed + connectionFailed, + connectionWillConnect } from './react/features/base/connection'; import { isFatalJitsiConnectionError, @@ -74,6 +75,7 @@ function checkForAttachParametersAndConnect(id, password, connection) { function connect(id, password, roomName) { const connectionConfig = Object.assign({}, config); const { issuer, jwt } = APP.store.getState()['features/base/jwt']; + const { locationURL } = APP.store.getState()['features/base/connection']; connectionConfig.bosh += `?room=${roomName}`; @@ -83,6 +85,8 @@ function connect(id, password, roomName) { jwt && issuer && issuer !== 'anonymous' ? jwt : undefined, connectionConfig); + APP.store.dispatch(connectionWillConnect(connection, locationURL)); + return new Promise((resolve, reject) => { connection.addEventListener( JitsiConnectionEvents.CONNECTION_ESTABLISHED, diff --git a/react/features/app/actions.js b/react/features/app/actions.js index e1a3d48c7..82bf73028 100644 --- a/react/features/app/actions.js +++ b/react/features/app/actions.js @@ -10,8 +10,10 @@ import { setConfig, storeConfig } from '../base/config'; -import { setLocationURL } from '../base/connection'; +import { connect, setLocationURL } from '../base/connection'; import { loadConfig } from '../base/lib-jitsi-meet'; +import { endAllSessions, findSessionForLocationURL } from '../base/session'; +import { createDesiredLocalTracks } from '../base/tracks'; import { parseURIString, toURLString } from '../base/util'; import { setFatalError } from '../overlay'; @@ -32,6 +34,8 @@ declare var APP: Object; */ export function appNavigate(uri: ?string) { return async (dispatch: Dispatch, getState: Function) => { + dispatch(endAllSessions()); + let location = parseURIString(uri); // If the specified location (URI) does not identify a host, use the app's @@ -81,7 +85,7 @@ export function appNavigate(uri: ?string) { config = restoreConfig(baseURL); if (!config) { - dispatch(loadConfigError(error, locationURL)); + dispatch(loadConfigError(error, locationURL, room)); return; } @@ -91,8 +95,15 @@ export function appNavigate(uri: ?string) { dispatch(setLocationURL(locationURL)); dispatch(setConfig(config)); dispatch(setRoom(room)); + + const session = findSessionForLocationURL(getState(), locationURL); + + if (session && typeof APP === 'undefined') { + dispatch(createDesiredLocalTracks()); + dispatch(connect()); + } } else { - dispatch(loadConfigError(new Error('Config no longer needed!'), locationURL)); + dispatch(loadConfigError(new Error('Config no longer needed!'), locationURL, room)); } }; } diff --git a/react/features/authentication/actions.js b/react/features/authentication/actions.js index dca227da2..d89a85dcf 100644 --- a/react/features/authentication/actions.js +++ b/react/features/authentication/actions.js @@ -113,6 +113,7 @@ export function cancelWaitForOwner() { // clients/consumers need an event. const { authRequired } = getState()['features/base/conference']; + // FIXME remove when external-api ported to base/session authRequired && dispatch(conferenceLeft(authRequired)); dispatch(appNavigate(undefined)); diff --git a/react/features/base/config/actions.js b/react/features/base/config/actions.js index 613bdd769..68d3ac189 100644 --- a/react/features/base/config/actions.js +++ b/react/features/base/config/actions.js @@ -38,17 +38,20 @@ export function configWillLoad(locationURL: URL, room: string) { * loading of a configuration. * @param {URL} locationURL - The URL of the location which necessitated the * loading of a configuration. + * @param {string} room - The name of the conference room. * @returns {{ * type: LOAD_CONFIG_ERROR, * error: Error, - * locationURL: URL + * locationURL: URL, + * room: string * }} */ -export function loadConfigError(error: Error, locationURL: URL) { +export function loadConfigError(error: Error, locationURL: URL, room: ?string) { return { type: LOAD_CONFIG_ERROR, error, - locationURL + locationURL, + room }; } diff --git a/react/features/base/connection/actions.native.js b/react/features/base/connection/actions.native.js index eb6475c13..a748ab57f 100644 --- a/react/features/base/connection/actions.native.js +++ b/react/features/base/connection/actions.native.js @@ -3,11 +3,6 @@ import _ from 'lodash'; import type { Dispatch } from 'redux'; -import { - conferenceLeft, - conferenceWillLeave, - getCurrentConference -} from '../conference'; import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet'; import { parseURIString } from '../util'; @@ -20,7 +15,7 @@ import { } from './actionTypes'; import { JITSI_CONNECTION_URL_KEY } from './constants'; -const logger = require('jitsi-meet-logger').getLogger(__filename); +import type JitsiConnection from 'lib-jitsi-meet/JitsiConnection'; /** * The error structure passed to the {@link connectionFailed} action. @@ -90,7 +85,7 @@ export function connect(id: ?string, password: ?string) { connection[JITSI_CONNECTION_URL_KEY] = locationURL; - dispatch(_connectionWillConnect(connection)); + dispatch(connectionWillConnect(connection, locationURL)); connection.addEventListener( JitsiConnectionEvents.CONNECTION_DISCONNECTED, @@ -258,16 +253,18 @@ export function connectionFailed( * * @param {JitsiConnection} connection - The {@code JitsiConnection} which will * connect. + * @param {URL} locationURL - FIXME. * @private * @returns {{ * type: CONNECTION_WILL_CONNECT, * connection: JitsiConnection * }} */ -function _connectionWillConnect(connection) { +export function connectionWillConnect(connection: JitsiConnection, locationURL: URL) { return { type: CONNECTION_WILL_CONNECT, - connection + connection, + locationURL }; } @@ -319,67 +316,6 @@ function _constructOptions(state) { return options; } -/** - * Closes connection. - * - * @returns {Function} - */ -export function disconnect() { - return (dispatch: Dispatch, getState: Function): Promise => { - const state = getState(); - - // The conference we have already joined or are joining. - const conference_ = getCurrentConference(state); - - // Promise which completes when the conference has been left and the - // connection has been disconnected. - let promise; - - // Leave the conference. - if (conference_) { - // In a fashion similar to JitsiConference's CONFERENCE_LEFT event - // (and the respective Redux action) which is fired after the - // conference has been left, notify the application about the - // intention to leave the conference. - dispatch(conferenceWillLeave(conference_)); - - promise - = conference_.leave() - .catch(error => { - logger.warn( - 'JitsiConference.leave() rejected with:', - error); - - // The library lib-jitsi-meet failed to make the - // JitsiConference leave. Which may be because - // JitsiConference thinks it has already left. - // Regardless of the failure reason, continue in - // jitsi-meet as if the leave has succeeded. - dispatch(conferenceLeft(conference_)); - }); - } else { - promise = Promise.resolve(); - } - - // Disconnect the connection. - const { connecting, connection } = state['features/base/connection']; - - // The connection we have already connected or are connecting. - const connection_ = connection || connecting; - - if (connection_) { - promise = promise.then(() => connection_.disconnect()); - } else { - // FIXME: We have no connection! Fake a disconnect. Because of how the current disconnec is implemented - // (by doing the diconnect() in the Conference component unmount) we have lost the location URL already. - // Oh well, at least send the event. - promise.then(() => dispatch(_connectionDisconnected({}, ''))); - } - - return promise; - }; -} - /** * Sets the location URL of the application, connecton, conference, etc. * diff --git a/react/features/base/connection/actions.web.js b/react/features/base/connection/actions.web.js index b625f9f1d..9312d78df 100644 --- a/react/features/base/connection/actions.web.js +++ b/react/features/base/connection/actions.web.js @@ -12,6 +12,7 @@ import { configureInitialDevices } from '../devices'; export { connectionEstablished, connectionFailed, + connectionWillConnect, setLocationURL } from './actions.native'; diff --git a/react/features/base/session/Session.js b/react/features/base/session/Session.js new file mode 100644 index 000000000..e793e9902 --- /dev/null +++ b/react/features/base/session/Session.js @@ -0,0 +1,86 @@ +// @flow + +import uuid from 'uuid'; + +import { toURLString } from '../util'; + +import type JitsiConference from 'lib-jitsi-meet/JitsiConference'; +import type JitsiConnection from 'lib-jitsi-meet/JitsiConnection'; + +/** + * FIXME. + */ +export class Session { + _conference: ?JitsiConference; + _connection: ?JitsiConnection; + conferenceFailed: boolean; + id: string; + locationURL: URL; + room: string; + + /** + * FIXME. + * + * @param {URL} locationURL - FIXME. + * @param {string} room - FIXME. + */ + constructor(locationURL: URL, room: string) { + this.locationURL = locationURL; + this.room = room; + this.id = uuid.v4().toUpperCase(); + this.conferenceFailed = false; + } + + /** + * FIXME. + * + * @param {JitsiConference} [conference] - FIXME. + */ + set conference(conference: ?JitsiConference) { + if (this._conference && conference && this._conference !== conference) { + throw new Error(`Attempt to reassign conference to ${this.toString()}`); + } + + this._conference = conference; + } + + /** + * FIXME. + * + * @returns {?JitsiConference} + */ + get conference(): ?JitsiConference { + return this._conference; + } + + /** + * FIXME. + * + * @param {JitsiConnection} [connection] - FIXME. + */ + set connection(connection: ?JitsiConnection) { + if (this._connection && connection && this._connection !== connection) { + throw new Error(`Attempt to reassign connection to ${this.toString()}`); + } + + this._connection = connection; + } + + /** + * FIXME. + * + * @returns {?JitsiConnection} + */ + get connection() { + return this._connection; + } + + /** + * FIXME. + * + * @returns {string} + */ + toString() { + return `Session[id=${this.id}, URL: ${toURLString(this.locationURL)} room: ${this.room}]`; + } +} diff --git a/react/features/base/session/actionTypes.js b/react/features/base/session/actionTypes.js new file mode 100644 index 000000000..222786584 --- /dev/null +++ b/react/features/base/session/actionTypes.js @@ -0,0 +1,8 @@ + +export const SESSION_CREATED = 'SESSION_CREATED'; + +export const SESSION_STARTED = 'SESSION_STARTED'; + +export const SESSION_TERMINATED = 'SESSION_TERMINATED'; + +export const SESSION_FAILED = 'SESSION_FAILED'; diff --git a/react/features/base/session/actions.js b/react/features/base/session/actions.js new file mode 100644 index 000000000..c5f477fa9 --- /dev/null +++ b/react/features/base/session/actions.js @@ -0,0 +1,135 @@ +// @flow + +import { conferenceLeft, conferenceWillLeave } from '../conference'; + +import { SESSION_CREATED, SESSION_FAILED, SESSION_STARTED, SESSION_TERMINATED } from './actionTypes'; +import { Session } from './Session'; + +import type { Dispatch } from 'redux'; + +const logger = require('jitsi-meet-logger').getLogger(__filename); + +/** + * FIXME. + * + * @returns {Function} + */ +export function endAllSessions() { + return (dispatch: Dispatch, getState: Function) => { + const sessions = getState()['features/base/session']; + + for (const session of sessions.values()) { + dispatch(endSession(session)); + } + }; +} + +/** + * FIXME. + * + * @param {Session} session - FIXME. + * @returns {function(*): *} + */ +export function endSession(session: Session) { + return (dispatch: Dispatch) => { + // The conference we have already joined or are joining. + const conference_ = session.conference; + + // Promise which completes when the conference has been left and the connection has been disconnected. + let promise; + + // Leave the conference. + if (conference_) { + // In a fashion similar to JitsiConference's CONFERENCE_LEFT event (and the respective Redux action) which + // is fired after the conference has been left, notify the application about the intention to leave + // the conference. + dispatch(conferenceWillLeave(conference_)); + + promise + = conference_.leave() + .catch(error => { + logger.warn('JitsiConference.leave() rejected with:', error); + + // The library lib-jitsi-meet failed to make the JitsiConference leave. Which may be because + // JitsiConference thinks it has already left. Regardless of the failure reason, continue in + // jitsi-meet as if the leave has succeeded. + dispatch(conferenceLeft(conference_)); + }); + } else { + promise = Promise.resolve(); + } + + const connection_ = session.connection; + + if (connection_) { + promise = promise.then(() => connection_.disconnect()); + } + + return promise; + }; +} + +/** + * FIXME. + * + * @param {URL} locationURL - FIXME. + * @param {string} room - FIXME. + * @returns {{ + * type: SESSION_CREATED, + * session: Session + * }} + */ +export function createSession(locationURL: URL, room: string) { + return { + type: SESSION_CREATED, + session: new Session(locationURL, room) + }; +} + +/** + * FIXME. + * + * @param {Session} session - FIXME. + * @returns {{ + * type: SESSION_FAILED, + * session: Session + * }} + */ +export function sessionFailed(session: Session) { + return { + type: SESSION_FAILED, + session + }; +} + +/** + * FIXME. + * + * @param {Session} session - FIXME. + * @returns {{ + * session: Session, + * type: string + * }} + */ +export function sessionStarted(session: Session) { + return { + type: SESSION_STARTED, + session + }; +} + +/** + * FIXME. + * + * @param {Session} session - FIXME. + * @returns {{ + * type: SESSION_TERMINATED, + * session: Session + * }} + */ +export function sessionTerminated(session: Session) { + return { + type: SESSION_TERMINATED, + session + }; +} diff --git a/react/features/base/session/index.js b/react/features/base/session/index.js new file mode 100644 index 000000000..88b59ff86 --- /dev/null +++ b/react/features/base/session/index.js @@ -0,0 +1,6 @@ +export * from './actions'; +export * from './actionTypes'; +export * from './selectors'; + +import './middleware'; +import './reducer'; diff --git a/react/features/base/session/middleware.js b/react/features/base/session/middleware.js new file mode 100644 index 000000000..05ebaba90 --- /dev/null +++ b/react/features/base/session/middleware.js @@ -0,0 +1,148 @@ +import { CONFERENCE_FAILED, CONFERENCE_JOINED, CONFERENCE_LEFT, CONFERENCE_WILL_JOIN } from '../conference'; +import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR } from '../config'; +import { CONNECTION_DISCONNECTED, CONNECTION_FAILED, CONNECTION_WILL_CONNECT } from '../connection'; +import { MiddlewareRegistry } from '../redux'; +import { toURLString } from '../util'; + +import { createSession, endSession, sessionFailed, sessionStarted, sessionTerminated } from './actions'; +import { SESSION_CREATED, SESSION_FAILED, SESSION_STARTED, SESSION_TERMINATED } from './actionTypes'; +import { findSessionForConference, findSessionForConnection, findSessionForLocationURL } from './selectors'; + + +MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { + const result = next(action); + + switch (action.type) { + case CONFERENCE_FAILED: { + const { conference, error } = action; + const { recoverable } = error; + const session = findSessionForConference(getState(), conference); + + if (session) { + session.conference = null; + if (typeof recoverable === 'undefined' || recoverable === false) { + session.conferenceFailed = true; + if (session.connection) { + // The sessionFailed is expected to be dispatched from either CONNECTION_DISCONNECTED + // or CONNECTION_FAILED handler in this middleware. The purpose is to delay the SESSION_FAILED until + // the XMPP connection is properly disposed. + dispatch(endSession(session)); + } else { + dispatch(sessionFailed(session)); + } + } + } else { + console.error('CONFERENCE_FAILED - no session found'); + } + break; + } + case CONFERENCE_LEFT: { + const { conference } = action; + const session = findSessionForConference(getState(), conference); + + if (session) { + session.conference = null; + + // If there's any existing connection wait for it to be closed first + session.connection || dispatch(sessionTerminated(session)); + } else { + console.error('CONFERENCE_LEFT - no session found'); + } + break; + } + case CONFERENCE_JOINED: { + const { conference } = action; + const session = findSessionForConference(getState(), conference); + + if (session) { + dispatch(sessionStarted(session)); + } else { + console.error('CONFERENCE_JOINED - no session found'); + } + + break; + } + case CONFERENCE_WILL_JOIN: { + const { conference } = action; + const { connection } = conference; + + const session = findSessionForConnection(getState(), connection); + + if (session) { + session.conference = conference; + } else { + console.error('CONFERENCE_WILL_JOIN - no session found'); + } + break; + } + case CONFIG_WILL_LOAD: { + const { locationURL, room } = action; + + room && room.length && dispatch(createSession(locationURL, room)); + + break; + } + case LOAD_CONFIG_ERROR: { + const { locationURL, room } = action; + + // There won't be a session if there's no room (it happen when the config is loaded for the welcome page). + if (room) { + const session = findSessionForLocationURL(getState(), locationURL); + + if (session) { + dispatch(sessionFailed(session)); + } else { + console.error(`LOAD_CONFIG_ERROR - no session found for: ${toURLString(locationURL)}`); + } + } + break; + } + case CONNECTION_DISCONNECTED: { + const { connection } = action; + const session = findSessionForConnection(getState(), connection); + + if (session) { + session.connection = null; + dispatch( + session.conferenceFailed ? sessionFailed(session) : sessionTerminated(session)); + } else { + console.error('CONNECTION_DISCONNECTED - no session found'); + } + break; + } + case CONNECTION_FAILED: { + const { connection, error } = action; + const { recoverable } = error; + const session = findSessionForConnection(getState(), connection); + + if (session) { + session.connection = null; + if (typeof recoverable === 'undefined' || recoverable === false) { + dispatch(sessionFailed(session)); + } + } else { + console.error('CONNECTION_FAILED - no session found'); + } + break; + } + case CONNECTION_WILL_CONNECT: { + const { connection, locationURL } = action; + const session = findSessionForLocationURL(getState(), locationURL); + + if (session) { + session.connection = connection; + } else { + console.error(`CONNECTION_WILL_CONNECT - no session found for: ${toURLString(locationURL)}`); + } + break; + } + case SESSION_CREATED: + case SESSION_STARTED: + case SESSION_FAILED: + case SESSION_TERMINATED: + console.info(`DEBUG ${action.type} ${action.session}`); + break; + } + + return result; +}); diff --git a/react/features/base/session/reducer.js b/react/features/base/session/reducer.js new file mode 100644 index 000000000..0671fcf16 --- /dev/null +++ b/react/features/base/session/reducer.js @@ -0,0 +1,27 @@ +import { ReducerRegistry } from '../redux'; + +import { SESSION_CREATED, SESSION_FAILED, SESSION_TERMINATED } from './actionTypes'; + +ReducerRegistry.register('features/base/session', (state = new Map(), action) => { + switch (action.type) { + case SESSION_CREATED: { + const { session } = action; + const nextMap = new Map(state); + + nextMap.set(session.id, session); + + return nextMap; + } + case SESSION_TERMINATED: + case SESSION_FAILED: { + const { session } = action; + const nextMap = new Map(state); + + nextMap.delete(session.id); + + return nextMap; + } + } + + return state; +}); diff --git a/react/features/base/session/selectors.js b/react/features/base/session/selectors.js new file mode 100644 index 000000000..e57b4e2c4 --- /dev/null +++ b/react/features/base/session/selectors.js @@ -0,0 +1,56 @@ +/** + * FIXME. + * + * @param {Object} state - FIXME. + * @param {JitsiConnection} connection - FIXME. + * @returns {Session|null} + */ +export function findSessionForConnection(state, connection) { + const sessions = state['features/base/session']; + + for (const session of sessions.values()) { + if (session.connection === connection) { + return session; + } + } + + return null; +} + +/** + * FIXME. + * + * @param {Object} state - FIXME. + * @param {JitsiConference} conference - FIXME. + * @returns {Session|null} + */ +export function findSessionForConference(state, conference) { + const sessions = state['features/base/session']; + + for (const session of sessions.values()) { + if (session.conference === conference) { + return session; + } + } + + return null; +} + +/** + * FIXME. + * + * @param {Object} state - FIXME. + * @param {URL} locationURL - FIXME. + * @returns {Session|null} + */ +export function findSessionForLocationURL(state, locationURL) { + const sessions = state['features/base/session']; + + for (const session of sessions.values()) { + if (session.locationURL === locationURL) { + return session; + } + } + + return null; +} diff --git a/react/features/conference/components/native/Conference.js b/react/features/conference/components/native/Conference.js index ab1961d2a..fb55298c4 100644 --- a/react/features/conference/components/native/Conference.js +++ b/react/features/conference/components/native/Conference.js @@ -5,7 +5,6 @@ import React from 'react'; import { BackHandler, SafeAreaView, StatusBar, View } from 'react-native'; import { appNavigate } from '../../../app'; -import { connect, disconnect } from '../../../base/connection'; import { getParticipantCount } from '../../../base/participants'; import { Container, LoadingIndicator, TintedView } from '../../../base/react'; import { connect as reactReduxConnect } from '../../../base/redux'; @@ -14,7 +13,6 @@ import { makeAspectRatioAware } from '../../../base/responsive-ui'; import { TestConnectionInfo } from '../../../base/testing'; -import { createDesiredLocalTracks } from '../../../base/tracks'; import { ConferenceNotification } from '../../../calendar-sync'; import { Chat } from '../../../chat'; import { DisplayNameLabel } from '../../../display-name'; @@ -66,21 +64,6 @@ type Props = AbstractProps & { */ _largeVideoParticipantId: string, - /** - * Current conference's full URL. - * - * @private - */ - _locationURL: URL, - - /** - * The handler which dispatches the (redux) action connect. - * - * @private - * @returns {void} - */ - _onConnect: Function, - /** * The handler which dispatches the (redux) action disconnect. * @@ -166,8 +149,6 @@ class Conference extends AbstractConference { * @returns {void} */ componentDidMount() { - this.props._onConnect(); - BackHandler.addEventListener( 'hardwareBackPress', this.props._onHardwareBackPress); @@ -186,24 +167,14 @@ class Conference extends AbstractConference { */ componentDidUpdate(pevProps: Props) { const { - _locationURL: oldLocationURL, - _participantCount: oldParticipantCount, - _room: oldRoom + _participantCount: oldParticipantCount } = pevProps; const { - _locationURL: newLocationURL, _participantCount: newParticipantCount, - _room: newRoom, _setToolboxVisible, _toolboxVisible } = this.props; - // If the location URL changes we need to reconnect. - oldLocationURL !== newLocationURL && newRoom && this.props._onDisconnect(); - - // Start the connection process when there is a (valid) room. - oldRoom !== newRoom && newRoom && this.props._onConnect(); - if (oldParticipantCount === 1 && newParticipantCount > 1 && _toolboxVisible) { @@ -228,8 +199,6 @@ class Conference extends AbstractConference { BackHandler.removeEventListener( 'hardwareBackPress', this.props._onHardwareBackPress); - - this.props._onDisconnect(); } /** @@ -396,36 +365,12 @@ class Conference extends AbstractConference { * @param {Function} dispatch - Redux action dispatcher. * @private * @returns {{ - * _onConnect: Function, - * _onDisconnect: Function, * _onHardwareBackPress: Function, * _setToolboxVisible: Function * }} */ function _mapDispatchToProps(dispatch) { return { - /** - * Dispatches actions to create the desired local tracks and for - * connecting to the conference. - * - * @private - * @returns {void} - */ - _onConnect() { - dispatch(createDesiredLocalTracks()); - dispatch(connect()); - }, - - /** - * Dispatches an action disconnecting from the conference. - * - * @private - * @returns {void} - */ - _onDisconnect() { - dispatch(disconnect()); - }, - /** * Handles a hardware button press for back navigation. Leaves the * associated {@code Conference}. @@ -462,8 +407,7 @@ function _mapDispatchToProps(dispatch) { * @returns {Props} */ function _mapStateToProps(state) { - const { connecting, connection, locationURL } - = state['features/base/connection']; + const { connecting, connection } = state['features/base/connection']; const { conference, joining, @@ -508,14 +452,6 @@ function _mapStateToProps(state) { */ _largeVideoParticipantId: state['features/large-video'].participantId, - /** - * Current conference's full URL. - * - * @private - * @type {URL} - */ - _locationURL: locationURL, - /** * The number of participants in the conference. *