Saúl Ibarra Corretgé 6e679f952f redux: refactor loading of middlewares and reducers
Up until now we relied on implicit loading of middlewares and reducers, through
having imports in each feature's index.js.

This leads to many complex import cycles which result in (sometimes) hard to fix
bugs in addition to (often) breaking mobile because a web-only feature gets
imported on mobile too, thanks to the implicit loading.

This PR changes that to make the process explicit. Both middlewares and reducers
are imported in a single place, the app entrypoint. They have been divided into
3 categories: any, web and native, which represent each of the platforms
  respectively.

Ideally no feature should have an index.js exporting actions, action types and
components, but that's a larger ordeal, so this is just the first step in
getting there. In order to both set example and avoid large cycles the app
feature has been refactored to not have an idex.js itself.
2020-06-16 11:24:15 +02:00

140 lines
4.4 KiB
JavaScript

// @flow
import type { Dispatch } from 'redux';
import {
appNavigate,
maybeRedirectToWelcomePage
} from '../app/actions';
import {
conferenceLeft,
JITSI_CONFERENCE_URL_KEY,
setPassword
} from '../base/conference';
import { hideDialog, openDialog } from '../base/dialog';
import { PasswordRequiredPrompt, RoomLockPrompt } from './components';
declare var APP: Object;
/**
* Begins a (user) request to lock a specific conference/room.
*
* @param {JitsiConference|undefined} conference - The JitsiConference to lock
* if specified or undefined if the current JitsiConference is to be locked.
* @returns {Function}
*/
export function beginRoomLockRequest(conference: ?Object) {
return (dispatch: Function, getState: Function) => {
if (typeof conference === 'undefined') {
// eslint-disable-next-line no-param-reassign
conference = getState()['features/base/conference'].conference;
}
if (conference) {
const passwordNumberOfDigits = getState()['features/base/config'].roomPasswordNumberOfDigits;
dispatch(openDialog(RoomLockPrompt, {
conference,
passwordNumberOfDigits }));
}
};
}
/**
* Cancels a prompt for a password to join a specific conference/room.
*
* @param {JitsiConference} conference - The {@code JitsiConference} requesting
* the password to join.
* @protected
* @returns {Function}
*/
export function _cancelPasswordRequiredPrompt(conference: Object) {
return (dispatch: Dispatch<any>, getState: Function) => {
if (typeof APP !== 'undefined') {
// when we are redirecting the library should handle any
// unload and clean of the connection.
APP.API.notifyReadyToClose();
dispatch(maybeRedirectToWelcomePage());
return;
}
// Canceling PasswordRequiredPrompt is to navigate the app/user to
// WelcomePage. In other words, the canceling invalidates the
// locationURL. Make sure that the canceling indeed has the intent to
// invalidate the locationURL.
const state = getState();
if (conference === state['features/base/conference'].passwordRequired
&& conference[JITSI_CONFERENCE_URL_KEY]
=== state['features/base/connection'].locationURL) {
// XXX The error associated with CONFERENCE_FAILED was marked as
// recoverable by the feature room-lock and, consequently,
// recoverable-aware features such as mobile's external-api did not
// deliver the CONFERENCE_FAILED to the SDK clients/consumers. Since
// the app/user is going to nativate to WelcomePage, the SDK
// clients/consumers need an event.
dispatch(conferenceLeft(conference));
dispatch(appNavigate(undefined));
}
};
}
/**
* Ends a (user) request to lock a specific conference/room.
*
* @param {JitsiConference} conference - The JitsiConference to lock.
* @param {string|undefined} password - The password with which the specified
* conference is to be locked or undefined to cancel the (user) request to lock
* the specified conference.
* @returns {Function}
*/
export function endRoomLockRequest(
conference: { lock: Function },
password: ?string) {
return (dispatch: Function) => {
const setPassword_
= password
? dispatch(setPassword(conference, conference.lock, password))
: Promise.resolve();
const endRoomLockRequest_ = () => dispatch(hideDialog(RoomLockPrompt));
setPassword_.then(endRoomLockRequest_, endRoomLockRequest_);
};
}
/**
* Begins a prompt for a password to join a specific conference/room.
*
* @param {JitsiConference} conference - The {@code JitsiConference}
* requesting the password to join.
* @protected
* @returns {{
* type: OPEN_DIALOG,
* component: Component,
* props: PropTypes
* }}
*/
export function _openPasswordRequiredPrompt(conference: Object) {
return openDialog(PasswordRequiredPrompt, { conference });
}
/**
* Unlocks the current jitsi conference.
*
* @returns {Function}
*/
export function unlockRoom() {
return (dispatch: Dispatch<any>, getState: Function) => {
const { conference } = getState()['features/base/conference'];
return dispatch(setPassword(
conference,
conference.lock,
''
));
};
}