[RN] Fix disconnecting before the connection was established

This commit is contained in:
Lyubo Marinov 2017-07-07 12:21:08 -05:00
parent c4232b34ae
commit 5c094bf6e0
5 changed files with 126 additions and 140 deletions

View File

@ -36,7 +36,6 @@ export const CONFERENCE_LEFT = Symbol('CONFERENCE_LEFT');
*
* {
* type: CONFERENCE_WILL_JOIN,
* room: string,
* conference: JitsiConference
* }
*/

View File

@ -195,23 +195,18 @@ export function conferenceLeft(conference) {
/**
* Signals the intention of the application to have the local participant join a
* conference with a specific room (name). Similar in fashion
* to CONFERENCE_JOINED.
* specific conference. Similar in fashion to {@code CONFERENCE_JOINED}.
*
* @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,
* conference: JitsiConference
* conference: JitsiConference
* }}
*/
function _conferenceWillJoin(room, conference) {
function _conferenceWillJoin(conference) {
return {
type: CONFERENCE_WILL_JOIN,
room,
conference
};
}
@ -247,13 +242,13 @@ export function createConference() {
const connection = state['features/base/connection'].connection;
if (!connection) {
throw new Error('Cannot create conference without connection');
throw new Error('Cannot create a conference without a connection!');
}
const { password, room } = state['features/base/conference'];
if (typeof room === 'undefined' || room === '') {
throw new Error('Cannot join conference without room name');
if (!room) {
throw new Error('Cannot join a conference without a room name!');
}
const conference
@ -263,7 +258,7 @@ export function createConference() {
room.toLowerCase(),
state['features/base/config']);
dispatch(_conferenceWillJoin(room, conference));
dispatch(_conferenceWillJoin(conference));
_addConferenceListeners(conference, dispatch);

View File

@ -71,43 +71,40 @@ ReducerRegistry.register('features/base/conference', (state = {}, action) => {
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _conferenceFailed(state, action) {
const conference = action.conference;
function _conferenceFailed(state, { conference, error }) {
if (state.conference && state.conference !== conference) {
return state;
}
const passwordRequired
= JitsiConferenceErrors.PASSWORD_REQUIRED === action.error
= JitsiConferenceErrors.PASSWORD_REQUIRED === error
? conference
: undefined;
return (
assign(state, {
audioOnly: undefined,
audioOnlyVideoMuted: undefined,
conference: undefined,
joining: undefined,
leaving: undefined,
return assign(state, {
audioOnly: undefined,
audioOnlyVideoMuted: undefined,
conference: undefined,
joining: undefined,
leaving: undefined,
/**
* The indicator of how the conference/room is locked. If falsy, the
* conference/room is unlocked; otherwise, it's either
* {@code LOCKED_LOCALLY} or {@code LOCKED_REMOTELY}.
*
* @type {string}
*/
locked: passwordRequired ? LOCKED_REMOTELY : undefined,
password: undefined,
/**
* The indicator of how the conference/room is locked. If falsy, the
* conference/room is unlocked; otherwise, it's either
* {@code LOCKED_LOCALLY} or {@code LOCKED_REMOTELY}.
*
* @type {string}
*/
locked: passwordRequired ? LOCKED_REMOTELY : undefined,
password: undefined,
/**
* The JitsiConference instance which requires a password to join.
*
* @type {JitsiConference}
*/
passwordRequired
}));
/**
* The JitsiConference instance which requires a password to join.
*
* @type {JitsiConference}
*/
passwordRequired
});
}
/**
@ -120,35 +117,32 @@ function _conferenceFailed(state, action) {
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _conferenceJoined(state, action) {
const conference = action.conference;
function _conferenceJoined(state, { conference }) {
// FIXME The indicator which determines whether a JitsiConference is locked
// i.e. password-protected is private to lib-jitsi-meet. However, the
// library does not fire LOCK_STATE_CHANGED upon joining a JitsiConference
// with a password.
const locked = conference.room.locked ? LOCKED_REMOTELY : undefined;
return (
assign(state, {
/**
* The JitsiConference instance represented by the Redux state of
* the feature base/conference.
*
* @type {JitsiConference}
*/
conference,
joining: undefined,
leaving: undefined,
return assign(state, {
/**
* The JitsiConference instance represented by the Redux state of the
* feature base/conference.
*
* @type {JitsiConference}
*/
conference,
joining: undefined,
leaving: undefined,
/**
* The indicator which determines whether the conference is locked.
*
* @type {boolean}
*/
locked,
passwordRequired: undefined
}));
/**
* The indicator which determines whether the conference is locked.
*
* @type {boolean}
*/
locked,
passwordRequired: undefined
});
}
/**
@ -161,24 +155,21 @@ function _conferenceJoined(state, action) {
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _conferenceLeft(state, action) {
const conference = action.conference;
function _conferenceLeft(state, { conference }) {
if (state.conference !== conference) {
return state;
}
return (
assign(state, {
audioOnly: undefined,
audioOnlyVideoMuted: undefined,
conference: undefined,
joining: undefined,
leaving: undefined,
locked: undefined,
password: undefined,
passwordRequired: undefined
}));
return assign(state, {
audioOnly: undefined,
audioOnlyVideoMuted: undefined,
conference: undefined,
joining: undefined,
leaving: undefined,
locked: undefined,
password: undefined,
passwordRequired: undefined
});
}
/**
@ -191,8 +182,8 @@ function _conferenceLeft(state, action) {
* @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);
function _conferenceWillJoin(state, { conference }) {
return set(state, 'joining', conference);
}
/**
@ -205,24 +196,23 @@ function _conferenceWillJoin(state, action) {
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _conferenceWillLeave(state, action) {
const conference = action.conference;
function _conferenceWillLeave(state, { conference }) {
if (state.conference !== conference) {
return state;
}
return (
assign(state, {
/**
* The JitsiConference instance which is currently in the process of
* being left.
*
* @type {JitsiConference}
*/
leaving: conference,
passwordRequired: undefined
}));
return assign(state, {
joining: undefined,
/**
* The JitsiConference instance which is currently in the process of
* being left.
*
* @type {JitsiConference}
*/
leaving: conference,
passwordRequired: undefined
});
}
/**
@ -235,20 +225,14 @@ function _conferenceWillLeave(state, action) {
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _lockStateChanged(state, action) {
if (state.conference !== action.conference) {
function _lockStateChanged(state, { conference, locked }) {
if (state.conference !== conference) {
return state;
}
let locked;
if (action.locked) {
locked = state.locked || LOCKED_REMOTELY;
}
return assign(state, {
locked,
password: action.locked ? state.password : null
locked: locked ? state.locked || LOCKED_REMOTELY : undefined,
password: locked ? state.password : undefined
});
}
@ -305,31 +289,28 @@ function _setLargeVideoHDStatus(state, action) {
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _setPassword(state, action) {
const conference = action.conference;
switch (action.method) {
function _setPassword(state, { conference, method, password }) {
switch (method) {
case conference.join:
if (state.passwordRequired === conference) {
return (
assign(state, {
locked: LOCKED_REMOTELY,
return assign(state, {
locked: LOCKED_REMOTELY,
/**
* The password with which the conference is to be joined.
*
* @type {string}
*/
password: action.password,
passwordRequired: undefined
}));
/**
* The password with which the conference is to be joined.
*
* @type {string}
*/
password,
passwordRequired: undefined
});
}
break;
case conference.lock:
return assign(state, {
locked: action.password ? LOCKED_LOCALLY : undefined,
password: action.password
locked: password ? LOCKED_LOCALLY : undefined,
password
});
}

View File

@ -211,34 +211,35 @@ export function disconnect() {
return (dispatch: Dispatch<*>, getState: Function) => {
const state = getState();
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;
const conference_ = conference || joining;
// 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());
const { connecting, connection } = state['features/base/connection'];
// The connection we are connecting or have already connected.
const connection_ = connection || connecting;
if (connection_) {
promise = promise.then(() => connection_.disconnect());
}
return promise;

View File

@ -49,11 +49,14 @@ ReducerRegistry.register(
function _connectionDisconnected(
state: Object,
{ connection }: { connection: Object }) {
if (state.connection === connection) {
return set(state, 'connection', undefined);
if (state.connection !== connection) {
return state;
}
return state;
return assign(state, {
connecting: undefined,
connection: undefined
});
}
/**
@ -75,8 +78,6 @@ function _connectionEstablished(
});
}
/* eslint-disable no-unused-vars */
/**
* Reduces a specific Redux action CONNECTION_FAILED of the feature
* base/connection.
@ -87,11 +88,18 @@ function _connectionEstablished(
* @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);
}
function _connectionFailed(
state: Object,
{ connection }: { connection: Object }) {
if (state.connection && state.connection !== connection) {
return state;
}
/* eslint-enable no-unused-vars */
return assign(state, {
connecting: undefined,
connection: undefined
});
}
/**
* Reduces a specific Redux action CONNECTION_WILL_CONNECT of the feature
@ -103,8 +111,10 @@ function _connectionFailed(state: Object, action: Object) {
* @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);
function _connectionWillConnect(
state: Object,
{ connection }: { connection: Object }) {
return set(state, 'connecting', connection);
}
/**