[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.
This commit is contained in:
Saúl Ibarra Corretgé 2017-07-06 13:51:35 +02:00 committed by Lyubo Marinov
parent 99b856233d
commit c4232b34ae
6 changed files with 121 additions and 14 deletions

View File

@ -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');

View File

@ -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);

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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);
}
/**