jiti-meet/react/features/base/session/middleware.js

165 lines
5.8 KiB
JavaScript

import { APP_WILL_NAVIGATE } from '../app';
import { CONFERENCE_FAILED, CONFERENCE_JOINED, CONFERENCE_LEFT, CONFERENCE_WILL_JOIN, SET_ROOM } from '../conference';
import { LOAD_CONFIG_ERROR } from '../config';
import { connect, CONNECTION_DISCONNECTED, CONNECTION_FAILED, CONNECTION_WILL_CONNECT } from '../connection';
import { MiddlewareRegistry } from '../redux';
import { createDesiredLocalTracks } from '../tracks';
import { toURLString } from '../util';
import { createSession, endAllSessions, 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 APP_WILL_NAVIGATE: {
const { locationURL, room } = action;
// Currently only one session is allowed at a time
dispatch(endAllSessions());
// Start a new session if there's a conference room name defined
room && room.length && dispatch(createSession(locationURL, room));
break;
}
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 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 SET_ROOM: {
const { locationURL } = getState()['features/base/connection'];
const session = findSessionForLocationURL(getState(), locationURL);
// Web has different logic for creating the local tracks and starting the connection
if (session && typeof APP === 'undefined') {
dispatch(createDesiredLocalTracks());
dispatch(connect());
}
break;
}
case SESSION_CREATED:
case SESSION_STARTED:
case SESSION_FAILED:
case SESSION_TERMINATED:
console.info(`DEBUG ${action.type} ${action.session}`);
break;
}
return result;
});