From c4232b34aeae2326dfe18a1398ce7420a2f3739b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Thu, 6 Jul 2017 13:51:35 +0200 Subject: [PATCH] [RN] Fix disconnecting before the connection was established Keep track of the connection and conference objects so we can leave and / or disconnect early, before the connection is established or the conference joined. --- react/features/base/conference/actionTypes.js | 3 +- react/features/base/conference/actions.js | 14 +++--- react/features/base/conference/reducer.js | 21 +++++++++ react/features/base/connection/actionTypes.js | 10 +++++ .../base/connection/actions.native.js | 42 ++++++++++++++--- react/features/base/connection/reducer.js | 45 ++++++++++++++++++- 6 files changed, 121 insertions(+), 14 deletions(-) diff --git a/react/features/base/conference/actionTypes.js b/react/features/base/conference/actionTypes.js index 4f52abeb0..79fd8cfc9 100644 --- a/react/features/base/conference/actionTypes.js +++ b/react/features/base/conference/actionTypes.js @@ -36,7 +36,8 @@ export const CONFERENCE_LEFT = Symbol('CONFERENCE_LEFT'); * * { * type: CONFERENCE_WILL_JOIN, - * room: string + * room: string, + * conference: JitsiConference * } */ export const CONFERENCE_WILL_JOIN = Symbol('CONFERENCE_WILL_JOIN'); diff --git a/react/features/base/conference/actions.js b/react/features/base/conference/actions.js index 71619acd7..6041f5d6d 100644 --- a/react/features/base/conference/actions.js +++ b/react/features/base/conference/actions.js @@ -200,15 +200,19 @@ export function conferenceLeft(conference) { * * @param {string} room - The room (name) which identifies the conference the * local participant will (try to) join. + * @param {JitsiConference} conference - The JitsiConference instance the + * local participant will (try to) join. * @returns {{ * type: CONFERENCE_WILL_JOIN, - * room: string + * room: string, +* conference: JitsiConference * }} */ -function _conferenceWillJoin(room) { +function _conferenceWillJoin(room, conference) { return { type: CONFERENCE_WILL_JOIN, - room + room, + conference }; } @@ -252,8 +256,6 @@ export function createConference() { throw new Error('Cannot join conference without room name'); } - dispatch(_conferenceWillJoin(room)); - const conference = connection.initJitsiConference( @@ -261,6 +263,8 @@ export function createConference() { room.toLowerCase(), state['features/base/config']); + dispatch(_conferenceWillJoin(room, conference)); + _addConferenceListeners(conference, dispatch); _setLocalParticipantData(conference, state); diff --git a/react/features/base/conference/reducer.js b/react/features/base/conference/reducer.js index e7614222a..c0c579e01 100644 --- a/react/features/base/conference/reducer.js +++ b/react/features/base/conference/reducer.js @@ -7,6 +7,7 @@ import { CONFERENCE_FAILED, CONFERENCE_JOINED, CONFERENCE_LEFT, + CONFERENCE_WILL_JOIN, CONFERENCE_WILL_LEAVE, LOCK_STATE_CHANGED, SET_AUDIO_ONLY, @@ -32,6 +33,9 @@ ReducerRegistry.register('features/base/conference', (state = {}, action) => { case CONFERENCE_LEFT: return _conferenceLeft(state, action); + case CONFERENCE_WILL_JOIN: + return _conferenceWillJoin(state, action); + case CONFERENCE_WILL_LEAVE: return _conferenceWillLeave(state, action); @@ -84,6 +88,7 @@ function _conferenceFailed(state, action) { audioOnly: undefined, audioOnlyVideoMuted: undefined, conference: undefined, + joining: undefined, leaving: undefined, /** @@ -133,6 +138,7 @@ function _conferenceJoined(state, action) { * @type {JitsiConference} */ conference, + joining: undefined, leaving: undefined, /** @@ -167,6 +173,7 @@ function _conferenceLeft(state, action) { audioOnly: undefined, audioOnlyVideoMuted: undefined, conference: undefined, + joining: undefined, leaving: undefined, locked: undefined, password: undefined, @@ -174,6 +181,20 @@ function _conferenceLeft(state, action) { })); } +/** + * Reduces a specific Redux action CONFERENCE_WILL_JOIN of the feature + * base/conference. + * + * @param {Object} state - The Redux state of the feature base/conference. + * @param {Action} action - The Redux action CONFERENCE_WILL_JOIN to reduce. + * @private + * @returns {Object} The new state of the feature base/conference after the + * reduction of the specified action. + */ +function _conferenceWillJoin(state, action) { + return set(state, 'joining', action.conference); +} + /** * Reduces a specific Redux action CONFERENCE_WILL_LEAVE of the feature * base/conference. diff --git a/react/features/base/connection/actionTypes.js b/react/features/base/connection/actionTypes.js index d628453a2..5d81f4a1c 100644 --- a/react/features/base/connection/actionTypes.js +++ b/react/features/base/connection/actionTypes.js @@ -32,6 +32,16 @@ export const CONNECTION_ESTABLISHED = Symbol('CONNECTION_ESTABLISHED'); */ export const CONNECTION_FAILED = Symbol('CONNECTION_FAILED'); +/** + * The type of (redux) action which signals that a connection will connect. + * + * { + * type: CONNECTION_WILL_CONNECT, + * connection: JitsiConnection + * } + */ +export const CONNECTION_WILL_CONNECT = Symbol('CONNECTION_WILL_CONNECT'); + /** * The type of (redux) action which sets the location URL of the application, * connection, conference, etc. diff --git a/react/features/base/connection/actions.native.js b/react/features/base/connection/actions.native.js index cd11084bd..48bfd533c 100644 --- a/react/features/base/connection/actions.native.js +++ b/react/features/base/connection/actions.native.js @@ -9,6 +9,7 @@ import { CONNECTION_DISCONNECTED, CONNECTION_ESTABLISHED, CONNECTION_FAILED, + CONNECTION_WILL_CONNECT, SET_LOCATION_URL } from './actionTypes'; @@ -49,6 +50,8 @@ export function connect() { jwt && issuer && issuer !== 'anonymous' ? jwt : undefined, options); + dispatch(_connectionWillConnect(connection)); + connection.addEventListener( JitsiConnectionEvents.CONNECTION_DISCONNECTED, _onConnectionDisconnected); @@ -138,6 +141,23 @@ function _connectionDisconnected(connection: Object, message: string) { }; } +/** + * Create an action for when a connection will connect. + * + * @param {JitsiConnection} connection - The JitsiConnection which will connect. + * @private + * @returns {{ + * type: CONNECTION_WILL_CONNECT, + * connection: JitsiConnection + * }} + */ +function _connectionWillConnect(connection) { + return { + type: CONNECTION_WILL_CONNECT, + connection + }; +} + /** * Create an action for when the signaling connection has been established. * @@ -190,27 +210,35 @@ export function connectionFailed( export function disconnect() { return (dispatch: Dispatch<*>, getState: Function) => { const state = getState(); - const { conference } = state['features/base/conference']; - const { connection } = state['features/base/connection']; + const { conference, joining } = state['features/base/conference']; + const { connection, connecting } = state['features/base/connection']; + // The conference we are joining or have already joined. + const _conference = joining || conference; + + // The connection we are connecting or have already connected. + const _connection = connecting || connection; + + // Promise which completes when the conference has been left and the + // connection has been disconnected. let promise; // Leave the conference. - if (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)); + dispatch(conferenceWillLeave(_conference)); - promise = conference.leave(); + promise = _conference.leave(); } else { promise = Promise.resolve(); } // Disconnect the connection. - if (connection) { - promise = promise.then(() => connection.disconnect()); + if (_connection) { + promise = promise.then(() => _connection.disconnect()); } return promise; diff --git a/react/features/base/connection/reducer.js b/react/features/base/connection/reducer.js index a9d6b613a..5302fce74 100644 --- a/react/features/base/connection/reducer.js +++ b/react/features/base/connection/reducer.js @@ -5,6 +5,8 @@ import { assign, ReducerRegistry, set } from '../redux'; import { CONNECTION_DISCONNECTED, CONNECTION_ESTABLISHED, + CONNECTION_FAILED, + CONNECTION_WILL_CONNECT, SET_LOCATION_URL } from './actionTypes'; @@ -21,6 +23,12 @@ ReducerRegistry.register( case CONNECTION_ESTABLISHED: return _connectionEstablished(state, action); + case CONNECTION_FAILED: + return _connectionFailed(state, action); + + case CONNECTION_WILL_CONNECT: + return _connectionWillConnect(state, action); + case SET_LOCATION_URL: return _setLocationURL(state, action); } @@ -61,7 +69,42 @@ function _connectionDisconnected( function _connectionEstablished( state: Object, { connection }: { connection: Object }) { - return set(state, 'connection', connection); + return assign(state, { + connecting: undefined, + connection + }); +} + +/* eslint-disable no-unused-vars */ + +/** + * Reduces a specific Redux action CONNECTION_FAILED of the feature + * base/connection. + * + * @param {Object} state - The Redux state of the feature base/connection. + * @param {Action} action - The Redux action CONNECTION_FAILED to reduce. + * @private + * @returns {Object} The new state of the feature base/connection after the + * reduction of the specified action. + */ +function _connectionFailed(state: Object, action: Object) { + return set(state, 'connecting', undefined); +} + +/* eslint-enable no-unused-vars */ + +/** + * Reduces a specific Redux action CONNECTION_WILL_CONNECT of the feature + * base/connection. + * + * @param {Object} state - The Redux state of the feature base/connection. + * @param {Action} action - The Redux action CONNECTION_WILL_CONNECT to reduce. + * @private + * @returns {Object} The new state of the feature base/connection after the + * reduction of the specified action. + */ +function _connectionWillConnect(state: Object, action: Object) { + return set(state, 'connecting', action.connection); } /**