[RN] Automatically dispatch CONFERENCE_LEFT
This commit is contained in:
parent
8b35ea8ad5
commit
a30412ba65
|
@ -20,6 +20,7 @@ import UIEvents from '../../../../service/UI/UIEvents';
|
|||
import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
|
||||
|
||||
import {
|
||||
conferenceLeft,
|
||||
createConference,
|
||||
setAudioOnly,
|
||||
setLastN,
|
||||
|
@ -32,8 +33,10 @@ import {
|
|||
DATA_CHANNEL_OPENED,
|
||||
SET_AUDIO_ONLY,
|
||||
SET_LASTN,
|
||||
SET_RECEIVE_VIDEO_QUALITY
|
||||
SET_RECEIVE_VIDEO_QUALITY,
|
||||
SET_ROOM
|
||||
} from './actionTypes';
|
||||
import { JITSI_CONFERENCE_URL_KEY } from './constants';
|
||||
import {
|
||||
_addLocalTracksToConference,
|
||||
_handleParticipantError,
|
||||
|
@ -77,6 +80,9 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
case SET_RECEIVE_VIDEO_QUALITY:
|
||||
return _setReceiveVideoQuality(store, next, action);
|
||||
|
||||
case SET_ROOM:
|
||||
return _setRoom(store, next, action);
|
||||
|
||||
case TRACK_ADDED:
|
||||
case TRACK_REMOVED:
|
||||
return _trackAddedOrRemoved(store, next, action);
|
||||
|
@ -330,6 +336,62 @@ function _setReceiveVideoQuality({ dispatch, getState }, next, action) {
|
|||
return next(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the feature {@code base/conference} that the redix action
|
||||
* {@link SET_ROOM} is being dispatched within a specific redux store.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified action is being
|
||||
* dispatched.
|
||||
* @param {Dispatch} next - The redux dispatch function to dispatch the
|
||||
* specified action to the specified store.
|
||||
* @param {Action} action - The redux action {@code SET_ROOM} which is being
|
||||
* dispatched in the specified store.
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _setRoom({ dispatch, getState }, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
// By the time SET_ROOM is dispatched, base/connection's locationURL and
|
||||
// base/conference's leaving should be the only conference-related sources
|
||||
// of truth.
|
||||
const state = getState();
|
||||
const {
|
||||
leaving,
|
||||
...stateFeaturesBaseConference
|
||||
} = state['features/base/conference'];
|
||||
const { locationURL } = state['features/base/connection'];
|
||||
const dispatchConferenceLeft = new Set();
|
||||
|
||||
// Figure out which of the JitsiConferences referenced by base/conference
|
||||
// have not dispatched or are not likely to dispatch CONFERENCE_FAILED and
|
||||
// CONFERENCE_LEFT.
|
||||
|
||||
// eslint-disable-next-line guard-for-in
|
||||
for (const p in stateFeaturesBaseConference) {
|
||||
const v = stateFeaturesBaseConference[p];
|
||||
|
||||
// Does the value of the base/conference's property look like a
|
||||
// JitsiConference?
|
||||
if (v && typeof v === 'object') {
|
||||
const url = v[JITSI_CONFERENCE_URL_KEY];
|
||||
|
||||
if (url && v !== leaving && url !== locationURL) {
|
||||
dispatchConferenceLeft.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch CONFERENCE_LEFT for the JitsiConferences referenced by
|
||||
// base/conference which have not dispatched or are not likely to dispatch
|
||||
// CONFERENCE_FAILED or CONFERENCE_LEFT.
|
||||
for (const conference of dispatchConferenceLeft) {
|
||||
dispatch(conferenceLeft(conference));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronizes local tracks from state with local tracks in JitsiConference
|
||||
* instance.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import _ from 'lodash';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { conferenceWillLeave } from '../conference';
|
||||
import { conferenceLeft, conferenceWillLeave } from '../conference';
|
||||
import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet';
|
||||
import { parseStandardURIString } from '../util';
|
||||
|
||||
|
@ -281,7 +281,16 @@ export function disconnect() {
|
|||
// intention to leave the conference.
|
||||
dispatch(conferenceWillLeave(conference_));
|
||||
|
||||
promise = conference_.leave();
|
||||
promise
|
||||
= conference_.leave()
|
||||
.catch(() => {
|
||||
// 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();
|
||||
}
|
||||
|
|
|
@ -125,11 +125,13 @@ function _getSymbolDescription(symbol: Symbol) {
|
|||
*/
|
||||
function _sendConferenceEvent(
|
||||
store: Object,
|
||||
{ conference, type, ...data }: {
|
||||
action: {
|
||||
conference: Object,
|
||||
type: Symbol,
|
||||
url: ?string
|
||||
}) {
|
||||
const { conference, type, ...data } = action;
|
||||
|
||||
// For these (redux) actions, conference identifies a JitsiConference
|
||||
// instance. The external API cannot transport such an object so we have to
|
||||
// transport an "equivalent".
|
||||
|
@ -137,7 +139,8 @@ function _sendConferenceEvent(
|
|||
data.url = toURLString(conference[JITSI_CONFERENCE_URL_KEY]);
|
||||
}
|
||||
|
||||
_sendEvent(store, _getSymbolDescription(type), data);
|
||||
_swallowEvent(store, action, data)
|
||||
|| _sendEvent(store, _getSymbolDescription(type), data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,3 +172,68 @@ function _sendEvent(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to not send a {@code CONFERENCE_LEFT} event to the native
|
||||
* counterpart of the External API.
|
||||
*
|
||||
* @param {Object} store - The redux store.
|
||||
* @param {Action} action - The redux action which is causing the sending of the
|
||||
* event.
|
||||
* @param {Object} data - The details/specifics of the event to send determined
|
||||
* by/associated with the specified {@code action}.
|
||||
* @returns {boolean} If the specified event is to not be sent, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
function _swallowConferenceLeft({ getState }, action, { url }) {
|
||||
// XXX Internally, we work with JitsiConference instances. Externally
|
||||
// though, we deal with URL strings. The relation between the two is many to
|
||||
// one so it's technically and practically possible (by externally loading
|
||||
// the same URL string multiple times) to try to send CONFERENCE_LEFT
|
||||
// externally for a URL string which identifies a JitsiConference that the
|
||||
// app is internally legitimately working with.
|
||||
|
||||
if (url) {
|
||||
const stateFeaturesBaseConference
|
||||
= getState()['features/base/conference'];
|
||||
|
||||
// eslint-disable-next-line guard-for-in
|
||||
for (const p in stateFeaturesBaseConference) {
|
||||
const v = stateFeaturesBaseConference[p];
|
||||
|
||||
// Does the value of the base/conference's property look like a
|
||||
// JitsiConference?
|
||||
if (v && typeof v === 'object') {
|
||||
const vURL = v[JITSI_CONFERENCE_URL_KEY];
|
||||
|
||||
if (vURL && vURL.toString() === url) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to not send a specific event to the native counterpart of
|
||||
* the External API.
|
||||
*
|
||||
* @param {Object} store - The redux store.
|
||||
* @param {Action} action - The redux action which is causing the sending of the
|
||||
* event.
|
||||
* @param {Object} data - The details/specifics of the event to send determined
|
||||
* by/associated with the specified {@code action}.
|
||||
* @returns {boolean} If the specified event is to not be sent, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
function _swallowEvent(store, action, data) {
|
||||
switch (action.type) {
|
||||
case CONFERENCE_LEFT:
|
||||
return _swallowConferenceLeft(store, action, data);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue