[RN] Simplify
There were getDomain, setDomain, SET_DOMAIN, setRoomURL, SET_ROOM_URL which together were repeating one and the same information and in the case of the 'room URL' abstraction was not 100% accurate because it would exist even when there was no room. Replace them all with a 'location URL' abstraction which exists with or without a room. Then the 'room URL' abstraction was not used in (mobile) feature share-room. Use the 'location URL' there now. Finally, removes source code duplication in supporting the Web application context root.
This commit is contained in:
parent
e6f6884c36
commit
2f3706bd37
|
@ -19,8 +19,7 @@ import analytics from './modules/analytics/analytics';
|
|||
|
||||
import EventEmitter from "events";
|
||||
|
||||
import { showDesktopSharingButton } from './react/features/toolbox';
|
||||
|
||||
import { getLocationContextRoot } from './react/features/app';
|
||||
import {
|
||||
AVATAR_ID_COMMAND,
|
||||
AVATAR_URL_COMMAND,
|
||||
|
@ -50,6 +49,7 @@ import {
|
|||
mediaPermissionPromptVisibilityChanged,
|
||||
suspendDetected
|
||||
} from './react/features/overlay';
|
||||
import { showDesktopSharingButton } from './react/features/toolbox';
|
||||
|
||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
|
@ -311,18 +311,11 @@ function assignWindowLocationPathname(pathname) {
|
|||
const windowLocation = window.location;
|
||||
|
||||
if (!pathname.startsWith('/')) {
|
||||
// XXX To support a deployment in a sub-directory, assume that the room
|
||||
// (name) is the last non-directory component of the path (name).
|
||||
let contextRoot = windowLocation.pathname;
|
||||
|
||||
contextRoot
|
||||
= contextRoot.substring(0, contextRoot.lastIndexOf('/') + 1);
|
||||
|
||||
// A pathname equal to ./ specifies the current directory. It will be
|
||||
// fine but pointless to include it because contextRoot is the current
|
||||
// directory.
|
||||
pathname.startsWith('./') && (pathname = pathname.substring(2));
|
||||
pathname = contextRoot + pathname;
|
||||
pathname = getLocationContextRoot(windowLocation) + pathname;
|
||||
}
|
||||
|
||||
windowLocation.pathname = pathname;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { setRoom, setRoomURL } from '../base/conference';
|
||||
import { setRoom } from '../base/conference';
|
||||
import { setLocationURL } from '../base/connection';
|
||||
import { setConfig } from '../base/config';
|
||||
import { getDomain, setDomain } from '../base/connection';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet';
|
||||
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||
|
@ -23,100 +23,151 @@ export function appInit() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Triggers an in-app navigation to a different route. Allows navigation to be
|
||||
* abstracted between the mobile and web versions.
|
||||
* Triggers an in-app navigation to a specific route. Allows navigation to be
|
||||
* abstracted between the mobile/React Native and Web/React applications.
|
||||
*
|
||||
* @param {(string|undefined)} uri - The URI to which to navigate. It may be a
|
||||
* full URL with an http(s) scheme, a full or partial URI with the app-specific
|
||||
* full URL with an HTTP(S) scheme, a full or partial URI with the app-specific
|
||||
* sheme, or a mere room name.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function appNavigate(uri) {
|
||||
return (dispatch: Dispatch<*>, getState: Function) => {
|
||||
const state = getState();
|
||||
const oldDomain = getDomain(state);
|
||||
const defaultURL = state['features/app'].app._getDefaultURL();
|
||||
let urlObject;
|
||||
export function appNavigate(uri: ?string) {
|
||||
return (dispatch: Dispatch<*>, getState: Function) =>
|
||||
_appNavigateToOptionalLocation(
|
||||
dispatch, getState,
|
||||
_parseURIString(uri));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { domain, room } = _parseURIString(uri);
|
||||
/**
|
||||
* Triggers an in-app navigation to a specific location URI.
|
||||
*
|
||||
* @param {Dispatch} dispatch - The redux {@code dispatch} function.
|
||||
* @param {Function} getState - The redux function that gets/retrieves the redux
|
||||
* state.
|
||||
* @param {Object} newLocation - The location URI to navigate to. The value
|
||||
* cannot be undefined and is assumed to have all properties such as
|
||||
* {@code host} and {@code room} defined values.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _appNavigateToMandatoryLocation(
|
||||
dispatch: Dispatch<*>, getState: Function,
|
||||
newLocation: Object) {
|
||||
// TODO Kostiantyn Tsaregradskyi: We should probably detect if user is
|
||||
// currently in a conference and ask her if she wants to close the
|
||||
// current conference and start a new one with the new room name or
|
||||
// domain.
|
||||
|
||||
// If the specified URI does not identify a domain, use the app's
|
||||
// default.
|
||||
if (typeof domain === 'undefined') {
|
||||
domain = _parseURIString(defaultURL).domain;
|
||||
const oldLocationURL = getState()['features/base/connection'].locationURL;
|
||||
const oldHost = oldLocationURL ? oldLocationURL.host : undefined;
|
||||
const newHost = newLocation.host;
|
||||
|
||||
if (oldHost === newHost) {
|
||||
dispatchSetLocationURL();
|
||||
dispatchSetRoomAndNavigate();
|
||||
} else {
|
||||
// If the host has changed, we need to load the config of the new host
|
||||
// and set it, and only after that we can navigate to a different route.
|
||||
_loadConfig(newLocation)
|
||||
.then(
|
||||
config => configLoaded(/* err */ undefined, config),
|
||||
err => configLoaded(err, /* config */ undefined))
|
||||
.then(dispatchSetRoomAndNavigate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that an attempt to load the config(uration) of domain has
|
||||
* completed.
|
||||
*
|
||||
* @param {string|undefined} err - If the loading has failed, the error
|
||||
* detailing the cause of the failure.
|
||||
* @param {Object|undefined} config - If the loading has succeeded, the
|
||||
* loaded config(uration).
|
||||
* @returns {void}
|
||||
*/
|
||||
function configLoaded(err, config) {
|
||||
if (err) {
|
||||
// XXX The failure could be, for example, because of a
|
||||
// certificate-related error. In which case the connection will
|
||||
// fail later in Strophe anyway even if we use the default
|
||||
// config here.
|
||||
|
||||
// The function loadConfig will log the err.
|
||||
return;
|
||||
}
|
||||
|
||||
if (room) {
|
||||
const splitURL = uri.split(domain);
|
||||
const urlWithoutDomain = splitURL[splitURL.length - 1];
|
||||
dispatchSetLocationURL();
|
||||
dispatch(setConfig(config));
|
||||
}
|
||||
|
||||
urlObject = new URL(urlWithoutDomain, `https://${domain}`);
|
||||
/**
|
||||
* Dispatches {@link setLocationURL} in the redux store.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function dispatchSetLocationURL() {
|
||||
dispatch(
|
||||
setLocationURL(
|
||||
new URL(
|
||||
(newLocation.protocol || 'https:')
|
||||
|
||||
// TODO userinfo
|
||||
|
||||
+ newLocation.host
|
||||
+ (newLocation.pathname || '/')
|
||||
+ newLocation.search
|
||||
+ newLocation.hash)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches {@link _setRoomAndNavigate} in the redux store.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function dispatchSetRoomAndNavigate() {
|
||||
dispatch(_setRoomAndNavigate(newLocation.room));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers an in-app navigation to a specific or undefined location (URI).
|
||||
*
|
||||
* @param {Dispatch} dispatch - The redux {@code dispatch} function.
|
||||
* @param {Function} getState - The redux function that gets/retrieves the redux
|
||||
* state.
|
||||
* @param {Object} location - The location (URI) to navigate to. The value may
|
||||
* be undefined.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _appNavigateToOptionalLocation(
|
||||
dispatch: Dispatch<*>, getState: Function,
|
||||
location: Object) {
|
||||
// If the specified location (URI) does not identify a host, use the app's
|
||||
// default.
|
||||
if (!location || !location.host) {
|
||||
const defaultLocation
|
||||
= _parseURIString(getState()['features/app'].app._getDefaultURL());
|
||||
|
||||
if (location) {
|
||||
location.host = defaultLocation.host;
|
||||
|
||||
// FIXME Turn location's host, hostname, and port properties into
|
||||
// setters in order to reduce the risks of inconsistent state.
|
||||
location.hostname = defaultLocation.hostname;
|
||||
location.port = defaultLocation.port;
|
||||
location.protocol = defaultLocation.protocol;
|
||||
} else {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
location = defaultLocation;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(setRoomURL(urlObject));
|
||||
if (!location.protocol) {
|
||||
location.protocol = 'https:';
|
||||
}
|
||||
|
||||
// TODO Kostiantyn Tsaregradskyi: We should probably detect if user is
|
||||
// currently in a conference and ask her if she wants to close the
|
||||
// current conference and start a new one with the new room name or
|
||||
// domain.
|
||||
|
||||
if (typeof domain === 'undefined' || oldDomain === domain) {
|
||||
dispatchSetRoomAndNavigate();
|
||||
} else if (oldDomain !== domain) {
|
||||
// Update domain without waiting for config to be loaded to prevent
|
||||
// race conditions when we will start to load config multiple times.
|
||||
dispatch(setDomain(domain));
|
||||
|
||||
// If domain has changed, we need to load the config of the new
|
||||
// domain and set it, and only after that we can navigate to a
|
||||
// different route.
|
||||
loadConfig(`https://${domain}`)
|
||||
.then(
|
||||
config => configLoaded(/* err */ undefined, config),
|
||||
err => configLoaded(err, /* config */ undefined))
|
||||
.then(dispatchSetRoomAndNavigate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that an attempt to load the config(uration) of domain has
|
||||
* completed.
|
||||
*
|
||||
* @param {string|undefined} err - If the loading has failed, the error
|
||||
* detailing the cause of the failure.
|
||||
* @param {Object|undefined} config - If the loading has succeeded, the
|
||||
* loaded config(uration).
|
||||
* @returns {void}
|
||||
*/
|
||||
function configLoaded(err, config) {
|
||||
if (err) {
|
||||
// XXX The failure could be, for example, because of a
|
||||
// certificate-related error. In which case the connection will
|
||||
// fail later in Strophe anyway even if we use the default
|
||||
// config here.
|
||||
|
||||
// The function loadConfig will log the err.
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(setConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches _setRoomAndNavigate in the Redux store.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function dispatchSetRoomAndNavigate() {
|
||||
// If both domain and room vars became undefined, that means we're
|
||||
// actually dealing with just room name and not with URL.
|
||||
dispatch(
|
||||
_setRoomAndNavigate(
|
||||
typeof room === 'undefined' && typeof domain === 'undefined'
|
||||
? uri
|
||||
: room));
|
||||
}
|
||||
};
|
||||
_appNavigateToMandatoryLocation(dispatch, getState, location);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,6 +202,27 @@ export function appWillUnmount(app) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads config.js from a specific host.
|
||||
*
|
||||
* @param {Object} location - The loction URI which specifies the host to load
|
||||
* the config.js from.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
function _loadConfig(location: Object) {
|
||||
let protocol = location.protocol.toLowerCase();
|
||||
|
||||
// The React Native app supports an app-specific scheme which is sure to not
|
||||
// be supported by fetch (or whatever loadConfig utilizes).
|
||||
if (protocol !== 'http:' && protocol !== 'https:') {
|
||||
protocol = 'https:';
|
||||
}
|
||||
|
||||
// TDOO userinfo
|
||||
|
||||
return loadConfig(protocol + location.host + (location.contextRoot || '/'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to a route in accord with a specific Redux state.
|
||||
*
|
||||
|
|
|
@ -268,13 +268,13 @@ export class AbstractApp extends Component {
|
|||
// By default, open the domain configured in the configuration file
|
||||
// which may be the domain at which the whole server infrastructure is
|
||||
// deployed.
|
||||
const config = this.props.config;
|
||||
const { config } = this.props;
|
||||
|
||||
if (typeof config === 'object') {
|
||||
const hosts = config.hosts;
|
||||
const { hosts } = config;
|
||||
|
||||
if (typeof hosts === 'object') {
|
||||
const domain = hosts.domain;
|
||||
const { domain } = hosts;
|
||||
|
||||
if (domain) {
|
||||
return `https://${domain}`;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { appInit } from '../actions';
|
||||
import { AbstractApp } from './AbstractApp';
|
||||
import { getLocationContextRoot } from '../functions';
|
||||
|
||||
import '../../room-lock';
|
||||
|
||||
|
@ -65,13 +66,7 @@ export class App extends AbstractApp {
|
|||
* @returns {string} The context root of window.location i.e. this Web App.
|
||||
*/
|
||||
_getWindowLocationContextRoot() {
|
||||
const pathname = this.getWindowLocation().pathname;
|
||||
const contextRootEndIndex = pathname.lastIndexOf('/');
|
||||
|
||||
return (
|
||||
contextRootEndIndex === -1
|
||||
? '/'
|
||||
: pathname.substring(0, contextRootEndIndex + 1));
|
||||
return getLocationContextRoot(this.getWindowLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -112,39 +112,21 @@ function _fixURIStringScheme(uri) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets room name and domain from URL object.
|
||||
* Gets the (Web application) context root defined by a specific location (URI).
|
||||
*
|
||||
* @param {URL} url - URL object.
|
||||
* @private
|
||||
* @returns {{
|
||||
* domain: (string|undefined),
|
||||
* room: (string|undefined)
|
||||
* }}
|
||||
* @param {Object} location - The location (URI) which defines the (Web
|
||||
* application) context root.
|
||||
* @returns {string} - The (Web application) context root defined by the
|
||||
* specified {@code location} (URI).
|
||||
*/
|
||||
function _getRoomAndDomainFromURLObject(url) {
|
||||
let domain;
|
||||
let room;
|
||||
export function getLocationContextRoot(location: Object) {
|
||||
const pathname = location.pathname;
|
||||
const contextRootEndIndex = pathname.lastIndexOf('/');
|
||||
|
||||
if (url) {
|
||||
domain = url.host;
|
||||
|
||||
// The room (name) is the last component of pathname.
|
||||
room = url.pathname;
|
||||
room = room.substring(room.lastIndexOf('/') + 1);
|
||||
|
||||
// Convert empty string to undefined to simplify checks.
|
||||
if (room === '') {
|
||||
room = undefined;
|
||||
}
|
||||
if (domain === '') {
|
||||
domain = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
domain,
|
||||
room
|
||||
};
|
||||
return (
|
||||
contextRootEndIndex === -1
|
||||
? '/'
|
||||
: pathname.substring(0, contextRootEndIndex + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,12 +142,113 @@ export function _getRouteToRender(stateOrGetState) {
|
|||
= typeof stateOrGetState === 'function'
|
||||
? stateOrGetState()
|
||||
: stateOrGetState;
|
||||
const room = state['features/base/conference'].room;
|
||||
const { room } = state['features/base/conference'];
|
||||
const component = isRoomValid(room) ? Conference : WelcomePage;
|
||||
|
||||
return RouteRegistry.getRouteByComponent(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a specific URI string into an object with the well-known properties of
|
||||
* the {@link Location} and/or {@link URL} interfaces implemented by Web
|
||||
* browsers. The parsing attempts to be in accord with IETF's RFC 3986.
|
||||
*
|
||||
* @param {string} str - The URI string to parse.
|
||||
* @returns {{
|
||||
* hash: string,
|
||||
* host: (string|undefined),
|
||||
* hostname: (string|undefined),
|
||||
* pathname: string,
|
||||
* port: (string|undefined),
|
||||
* protocol: (string|undefined),
|
||||
* search: string
|
||||
* }}
|
||||
*/
|
||||
function _parseStandardURIString(str: string) {
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
const obj = {};
|
||||
|
||||
let regex;
|
||||
let match;
|
||||
|
||||
// protocol
|
||||
regex = new RegExp(`^${_URI_PROTOCOL_PATTERN}`, 'gi');
|
||||
match = regex.exec(str);
|
||||
if (match) {
|
||||
obj.protocol = match[1].toLowerCase();
|
||||
str = str.substring(regex.lastIndex);
|
||||
}
|
||||
|
||||
// authority
|
||||
regex = new RegExp(`^${_URI_AUTHORITY_PATTERN}`, 'gi');
|
||||
match = regex.exec(str);
|
||||
if (match) {
|
||||
let authority = match[1].substring(/* // */ 2);
|
||||
|
||||
str = str.substring(regex.lastIndex);
|
||||
|
||||
// userinfo
|
||||
const userinfoEndIndex = authority.indexOf('@');
|
||||
|
||||
if (userinfoEndIndex !== -1) {
|
||||
authority = authority.substring(userinfoEndIndex + 1);
|
||||
}
|
||||
|
||||
obj.host = authority;
|
||||
|
||||
// port
|
||||
const portBeginIndex = authority.lastIndexOf(':');
|
||||
|
||||
if (portBeginIndex !== -1) {
|
||||
obj.port = authority.substring(portBeginIndex + 1);
|
||||
authority = authority.substring(0, portBeginIndex);
|
||||
}
|
||||
|
||||
// hostname
|
||||
obj.hostname = authority;
|
||||
}
|
||||
|
||||
// pathname
|
||||
regex = new RegExp(`^${_URI_PATH_PATTERN}`, 'gi');
|
||||
match = regex.exec(str);
|
||||
|
||||
let pathname;
|
||||
|
||||
if (match) {
|
||||
pathname = match[1];
|
||||
str = str.substring(regex.lastIndex);
|
||||
}
|
||||
if (pathname) {
|
||||
if (!pathname.startsWith('/')) {
|
||||
pathname = `/${pathname}`;
|
||||
}
|
||||
} else {
|
||||
pathname = '/';
|
||||
}
|
||||
obj.pathname = pathname;
|
||||
|
||||
// query
|
||||
if (str.startsWith('?')) {
|
||||
let hashBeginIndex = str.indexOf('#', 1);
|
||||
|
||||
if (hashBeginIndex === -1) {
|
||||
hashBeginIndex = str.length;
|
||||
}
|
||||
obj.search = str.substring(0, hashBeginIndex);
|
||||
str = str.substring(hashBeginIndex);
|
||||
} else {
|
||||
obj.search = ''; // Google Chrome
|
||||
}
|
||||
|
||||
// fragment
|
||||
obj.hash = str.startsWith('#') ? str : '';
|
||||
|
||||
/* eslint-enable no-param-reassign */
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a specific URI which (supposedly) references a Jitsi Meet resource
|
||||
* (location).
|
||||
|
@ -173,68 +256,28 @@ export function _getRouteToRender(stateOrGetState) {
|
|||
* @param {(string|undefined)} uri - The URI to parse which (supposedly)
|
||||
* references a Jitsi Meet resource (location).
|
||||
* @returns {{
|
||||
* domain: (string|undefined),
|
||||
* room: (string|undefined)
|
||||
* }}
|
||||
*/
|
||||
export function _parseURIString(uri) {
|
||||
let obj;
|
||||
|
||||
if (typeof uri === 'string') {
|
||||
let str = uri;
|
||||
|
||||
str = _fixURIStringScheme(str);
|
||||
str = _fixURIStringHierPart(str);
|
||||
|
||||
obj = {};
|
||||
|
||||
let regex;
|
||||
let match;
|
||||
|
||||
// protocol
|
||||
regex = new RegExp(`^${_URI_PROTOCOL_PATTERN}`, 'gi');
|
||||
match = regex.exec(str);
|
||||
if (match) {
|
||||
obj.protocol = match[1].toLowerCase();
|
||||
str = str.substring(regex.lastIndex);
|
||||
}
|
||||
|
||||
// authority
|
||||
regex = new RegExp(`^${_URI_AUTHORITY_PATTERN}`, 'gi');
|
||||
match = regex.exec(str);
|
||||
if (match) {
|
||||
let authority = match[1].substring(/* // */ 2);
|
||||
|
||||
str = str.substring(regex.lastIndex);
|
||||
|
||||
// userinfo
|
||||
const userinfoEndIndex = authority.indexOf('@');
|
||||
|
||||
if (userinfoEndIndex !== -1) {
|
||||
authority = authority.substring(userinfoEndIndex + 1);
|
||||
}
|
||||
|
||||
obj.host = authority;
|
||||
|
||||
// port
|
||||
const portBeginIndex = authority.lastIndexOf(':');
|
||||
|
||||
if (portBeginIndex !== -1) {
|
||||
obj.port = authority.substring(portBeginIndex + 1);
|
||||
authority = authority.substring(0, portBeginIndex);
|
||||
}
|
||||
|
||||
obj.hostname = authority;
|
||||
}
|
||||
|
||||
// pathname
|
||||
regex = new RegExp(`^${_URI_PATH_PATTERN}`, 'gi');
|
||||
match = regex.exec(str);
|
||||
if (match) {
|
||||
obj.pathname = match[1] || '/';
|
||||
str = str.substring(regex.lastIndex);
|
||||
}
|
||||
export function _parseURIString(uri: ?string) {
|
||||
if (typeof uri !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return _getRoomAndDomainFromURLObject(obj);
|
||||
const obj
|
||||
= _parseStandardURIString(
|
||||
_fixURIStringHierPart(_fixURIStringScheme(uri)));
|
||||
|
||||
// Add the properties that are specific to a Jitsi Meet resource (location)
|
||||
// such as contextRoot, room:
|
||||
|
||||
// contextRoot
|
||||
obj.contextRoot = getLocationContextRoot(obj);
|
||||
|
||||
// The room (name) is the last component of pathname.
|
||||
const { pathname } = obj;
|
||||
|
||||
obj.room = pathname.substring(pathname.lastIndexOf('/') + 1) || undefined;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ const _INTERCEPT_COMPONENT_RULES = [
|
|||
}
|
||||
];
|
||||
|
||||
export { _parseURIString } from './functions.native';
|
||||
export { getLocationContextRoot, _parseURIString } from './functions.native';
|
||||
|
||||
/**
|
||||
* Determines which route is to be rendered in order to depict a specific Redux
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Symbol } from '../react';
|
||||
|
||||
/**
|
||||
* The type of the Redux action which signals that a specific conference has
|
||||
* failed.
|
||||
* The type of (redux) action which signals that a specific conference failed.
|
||||
*
|
||||
* {
|
||||
* type: CONFERENCE_FAILED,
|
||||
|
@ -13,8 +12,8 @@ import { Symbol } from '../react';
|
|||
export const CONFERENCE_FAILED = Symbol('CONFERENCE_FAILED');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which signals that a specific conference has
|
||||
* been joined.
|
||||
* The type of (redux) action which signals that a specific conference was
|
||||
* joined.
|
||||
*
|
||||
* {
|
||||
* type: CONFERENCE_JOINED,
|
||||
|
@ -24,8 +23,7 @@ export const CONFERENCE_FAILED = Symbol('CONFERENCE_FAILED');
|
|||
export const CONFERENCE_JOINED = Symbol('CONFERENCE_JOINED');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which signals that a specific conference has
|
||||
* been left.
|
||||
* The type of (redux) action which signals that a specific conference was left.
|
||||
*
|
||||
* {
|
||||
* type: CONFERENCE_LEFT,
|
||||
|
@ -35,7 +33,7 @@ export const CONFERENCE_JOINED = Symbol('CONFERENCE_JOINED');
|
|||
export const CONFERENCE_LEFT = Symbol('CONFERENCE_LEFT');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which signals that a specific conference will be
|
||||
* The type of (redux) action which signals that a specific conference will be
|
||||
* joined.
|
||||
*
|
||||
* {
|
||||
|
@ -46,7 +44,7 @@ export const CONFERENCE_LEFT = Symbol('CONFERENCE_LEFT');
|
|||
export const CONFERENCE_WILL_JOIN = Symbol('CONFERENCE_WILL_JOIN');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which signals that a specific conference will be
|
||||
* The type of (redux) action which signals that a specific conference will be
|
||||
* left.
|
||||
*
|
||||
* {
|
||||
|
@ -57,8 +55,8 @@ export const CONFERENCE_WILL_JOIN = Symbol('CONFERENCE_WILL_JOIN');
|
|||
export const CONFERENCE_WILL_LEAVE = Symbol('CONFERENCE_WILL_LEAVE');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which signals that the lock state of a specific
|
||||
* <tt>JitsiConference</tt> changed.
|
||||
* The type of (redux) action which signals that the lock state of a specific
|
||||
* {@code JitsiConference} changed.
|
||||
*
|
||||
* {
|
||||
* type: LOCK_STATE_CHANGED,
|
||||
|
@ -69,7 +67,7 @@ export const CONFERENCE_WILL_LEAVE = Symbol('CONFERENCE_WILL_LEAVE');
|
|||
export const LOCK_STATE_CHANGED = Symbol('LOCK_STATE_CHANGED');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which sets the audio-only flag for the current
|
||||
* The type of (redux) action which sets the audio-only flag for the current
|
||||
* conference.
|
||||
*
|
||||
* {
|
||||
|
@ -80,8 +78,8 @@ export const LOCK_STATE_CHANGED = Symbol('LOCK_STATE_CHANGED');
|
|||
export const SET_AUDIO_ONLY = Symbol('SET_AUDIO_ONLY');
|
||||
|
||||
/**
|
||||
* The type of redux action which signals that video will be muted because the
|
||||
* audio-only mode was enabled / disabled.
|
||||
* The type of (redux) action which signals that video will be muted because the
|
||||
* audio-only mode was enabled/disabled.
|
||||
*
|
||||
* {
|
||||
* type: _SET_AUDIO_ONLY_VIDEO_MUTED,
|
||||
|
@ -105,7 +103,7 @@ export const _SET_AUDIO_ONLY_VIDEO_MUTED
|
|||
export const SET_LARGE_VIDEO_HD_STATUS = Symbol('SET_LARGE_VIDEO_HD_STATUS');
|
||||
|
||||
/**
|
||||
* The type of redux action which sets the video channel's lastN (value).
|
||||
* The type of (redux) action which sets the video channel's lastN (value).
|
||||
*
|
||||
* {
|
||||
* type: SET_LASTN,
|
||||
|
@ -115,8 +113,8 @@ export const SET_LARGE_VIDEO_HD_STATUS = Symbol('SET_LARGE_VIDEO_HD_STATUS');
|
|||
export const SET_LASTN = Symbol('SET_LASTN');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which sets the password to join or lock a
|
||||
* specific JitsiConference.
|
||||
* The type of (redux) action which sets the password to join or lock a specific
|
||||
* {@code JitsiConference}.
|
||||
*
|
||||
* {
|
||||
* type: SET_PASSWORD,
|
||||
|
@ -128,8 +126,8 @@ export const SET_LASTN = Symbol('SET_LASTN');
|
|||
export const SET_PASSWORD = Symbol('SET_PASSWORD');
|
||||
|
||||
/**
|
||||
* The type of Redux action which signals that setting a password on a
|
||||
* JitsiConference failed (with an error).
|
||||
* The type of (redux) action which signals that setting a password on a
|
||||
* {@code JitsiConference} failed (with an error).
|
||||
*
|
||||
* {
|
||||
* type: SET_PASSWORD_FAILED,
|
||||
|
@ -139,7 +137,7 @@ export const SET_PASSWORD = Symbol('SET_PASSWORD');
|
|||
export const SET_PASSWORD_FAILED = Symbol('SET_PASSWORD_FAILED');
|
||||
|
||||
/**
|
||||
* The type of the Redux action which sets the name of the room of the
|
||||
* The type of (redux) action which sets the name of the room of the
|
||||
* conference to be joined.
|
||||
*
|
||||
* {
|
||||
|
@ -148,13 +146,3 @@ export const SET_PASSWORD_FAILED = Symbol('SET_PASSWORD_FAILED');
|
|||
* }
|
||||
*/
|
||||
export const SET_ROOM = Symbol('SET_ROOM');
|
||||
|
||||
/**
|
||||
* The type of (Redux) action which sets the room URL.
|
||||
*
|
||||
* {
|
||||
* type: SET_ROOM_URL,
|
||||
* roomURL: URL
|
||||
* }
|
||||
*/
|
||||
export const SET_ROOM_URL = Symbol('SET_ROOM_URL');
|
||||
|
|
|
@ -24,8 +24,7 @@ import {
|
|||
SET_LASTN,
|
||||
SET_PASSWORD,
|
||||
SET_PASSWORD_FAILED,
|
||||
SET_ROOM,
|
||||
SET_ROOM_URL
|
||||
SET_ROOM
|
||||
} from './actionTypes';
|
||||
import {
|
||||
AVATAR_ID_COMMAND,
|
||||
|
@ -491,22 +490,6 @@ export function setRoom(room) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the room URL.
|
||||
*
|
||||
* @param {string} roomURL - Room url.
|
||||
* @returns {{
|
||||
* type: SET_ROOM_URL,
|
||||
* roomURL: URL
|
||||
* }}
|
||||
*/
|
||||
export function setRoomURL(roomURL) {
|
||||
return {
|
||||
type: SET_ROOM_URL,
|
||||
roomURL
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the audio-only flag for the current JitsiConference.
|
||||
*
|
||||
|
|
|
@ -13,8 +13,7 @@ import {
|
|||
_SET_AUDIO_ONLY_VIDEO_MUTED,
|
||||
SET_LARGE_VIDEO_HD_STATUS,
|
||||
SET_PASSWORD,
|
||||
SET_ROOM,
|
||||
SET_ROOM_URL
|
||||
SET_ROOM
|
||||
} from './actionTypes';
|
||||
import { isRoomValid } from './functions';
|
||||
|
||||
|
@ -53,9 +52,6 @@ ReducerRegistry.register('features/base/conference', (state = {}, action) => {
|
|||
|
||||
case SET_ROOM:
|
||||
return _setRoom(state, action);
|
||||
|
||||
case SET_ROOM_URL:
|
||||
return _setRoomURL(state, action);
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -348,23 +344,3 @@ function _setRoom(state, action) {
|
|||
*/
|
||||
return set(state, 'room', room);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces a specific Redux action SET_ROOM_URL of the feature base/conference.
|
||||
*
|
||||
* @param {Object} state - The Redux state of the feature base/conference.
|
||||
* @param {Action} action - The Redux action SET_ROOM_URL to reduce.
|
||||
* @private
|
||||
* @returns {Object} The new state of the feature base/conference after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _setRoomURL(state, action) {
|
||||
const { roomURL } = action;
|
||||
|
||||
/**
|
||||
* Room URL of the conference (to be) joined.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
return set(state, 'roomURL', roomURL);
|
||||
}
|
||||
|
|
|
@ -1,26 +1,46 @@
|
|||
import { Symbol } from '../react';
|
||||
|
||||
/**
|
||||
* Action type to signal that connection has disconnected.
|
||||
* The type of (redux) action which signals that a connection disconnected.
|
||||
*
|
||||
* {
|
||||
* type: CONNECTION_DISCONNECTED,
|
||||
* connection: JitsiConnection,
|
||||
* message: string
|
||||
* }
|
||||
*/
|
||||
export const CONNECTION_DISCONNECTED = Symbol('CONNECTION_DISCONNECTED');
|
||||
|
||||
/**
|
||||
* Action type to signal that have successfully established a connection.
|
||||
* The type of (redux) action which signals that a connection was successfully
|
||||
* established.
|
||||
*
|
||||
* {
|
||||
* type: CONNECTION_ESTABLISHED,
|
||||
* connection: JitsiConnection
|
||||
* }
|
||||
*/
|
||||
export const CONNECTION_ESTABLISHED = Symbol('CONNECTION_ESTABLISHED');
|
||||
|
||||
/**
|
||||
* Action type to signal a connection failed.
|
||||
* The type of (redux) action which signals that a connection failed.
|
||||
*
|
||||
* {
|
||||
* type: CONNECTION_FAILED,
|
||||
* connection: JitsiConnection,
|
||||
* error: string,
|
||||
* message: string
|
||||
* }
|
||||
*/
|
||||
export const CONNECTION_FAILED = Symbol('CONNECTION_FAILED');
|
||||
|
||||
/**
|
||||
* Action to signal to change connection domain.
|
||||
* The type of (redux) action which sets the location URL of the application,
|
||||
* connection, conference, etc.
|
||||
*
|
||||
* {
|
||||
* type: SET_DOMAIN,
|
||||
* domain: string
|
||||
* type: SET_LOCATION_URL,
|
||||
* locationURL: ?URL
|
||||
* }
|
||||
*/
|
||||
export const SET_DOMAIN = Symbol('SET_DOMAIN');
|
||||
export const SET_LOCATION_URL = Symbol('SET_LOCATION_URL');
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
CONNECTION_DISCONNECTED,
|
||||
CONNECTION_ESTABLISHED,
|
||||
CONNECTION_FAILED,
|
||||
SET_DOMAIN
|
||||
SET_LOCATION_URL
|
||||
} from './actionTypes';
|
||||
|
||||
/**
|
||||
|
@ -88,7 +88,7 @@ export function connect() {
|
|||
function _onConnectionFailed(err) {
|
||||
unsubscribe();
|
||||
console.error('CONNECTION FAILED:', err);
|
||||
dispatch(connectionFailed(connection, err, ''));
|
||||
dispatch(connectionFailed(connection, err));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,6 +108,70 @@ export function connect() {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action for when the signaling connection has been lost.
|
||||
*
|
||||
* @param {JitsiConnection} connection - The JitsiConnection which disconnected.
|
||||
* @param {string} message - Error message.
|
||||
* @private
|
||||
* @returns {{
|
||||
* type: CONNECTION_DISCONNECTED,
|
||||
* connection: JitsiConnection,
|
||||
* message: string
|
||||
* }}
|
||||
*/
|
||||
function _connectionDisconnected(connection: Object, message: string) {
|
||||
return {
|
||||
type: CONNECTION_DISCONNECTED,
|
||||
connection,
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action for when the signaling connection has been established.
|
||||
*
|
||||
* @param {JitsiConnection} connection - The JitsiConnection which was
|
||||
* established.
|
||||
* @public
|
||||
* @returns {{
|
||||
* type: CONNECTION_ESTABLISHED,
|
||||
* connection: JitsiConnection
|
||||
* }}
|
||||
*/
|
||||
export function connectionEstablished(connection: Object) {
|
||||
return {
|
||||
type: CONNECTION_ESTABLISHED,
|
||||
connection
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action for when the signaling connection could not be created.
|
||||
*
|
||||
* @param {JitsiConnection} connection - The JitsiConnection which failed.
|
||||
* @param {string} error - Error.
|
||||
* @param {string} message - Error message.
|
||||
* @public
|
||||
* @returns {{
|
||||
* type: CONNECTION_FAILED,
|
||||
* connection: JitsiConnection,
|
||||
* error: string,
|
||||
* message: string
|
||||
* }}
|
||||
*/
|
||||
export function connectionFailed(
|
||||
connection: Object,
|
||||
error: string,
|
||||
message: ?string) {
|
||||
return {
|
||||
type: CONNECTION_FAILED,
|
||||
connection,
|
||||
error,
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes connection.
|
||||
*
|
||||
|
@ -116,8 +180,8 @@ export function connect() {
|
|||
export function disconnect() {
|
||||
return (dispatch: Dispatch<*>, getState: Function) => {
|
||||
const state = getState();
|
||||
const conference = state['features/base/conference'].conference;
|
||||
const connection = state['features/base/connection'].connection;
|
||||
const { conference } = state['features/base/conference'];
|
||||
const { connection } = state['features/base/connection'];
|
||||
|
||||
let promise;
|
||||
|
||||
|
@ -144,79 +208,18 @@ export function disconnect() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets connection domain.
|
||||
* Sets the location URL of the application, connecton, conference, etc.
|
||||
*
|
||||
* @param {string} domain - Domain name.
|
||||
* @param {URL} [locationURL] - The location URL of the application,
|
||||
* connection, conference, etc.
|
||||
* @returns {{
|
||||
* type: SET_DOMAIN,
|
||||
* domain: string
|
||||
* }}
|
||||
*/
|
||||
export function setDomain(domain: string) {
|
||||
return {
|
||||
type: SET_DOMAIN,
|
||||
domain
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action for when the signaling connection has been lost.
|
||||
*
|
||||
* @param {JitsiConnection} connection - The JitsiConnection which disconnected.
|
||||
* @param {string} message - Error message.
|
||||
* @private
|
||||
* @returns {{
|
||||
* type: CONNECTION_DISCONNECTED,
|
||||
* connection: JitsiConnection,
|
||||
* message: string
|
||||
* type: SET_LOCATION_URL,
|
||||
* locationURL: URL
|
||||
* }}
|
||||
*/
|
||||
function _connectionDisconnected(connection, message: string) {
|
||||
export function setLocationURL(locationURL: ?URL) {
|
||||
return {
|
||||
type: CONNECTION_DISCONNECTED,
|
||||
connection,
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action for when the signaling connection has been established.
|
||||
*
|
||||
* @param {JitsiConnection} connection - The JitsiConnection which was
|
||||
* established.
|
||||
* @returns {{
|
||||
* type: CONNECTION_ESTABLISHED,
|
||||
* connection: JitsiConnection
|
||||
* }}
|
||||
* @public
|
||||
*/
|
||||
export function connectionEstablished(connection: Object) {
|
||||
return {
|
||||
type: CONNECTION_ESTABLISHED,
|
||||
connection
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action for when the signaling connection could not be created.
|
||||
*
|
||||
* @param {JitsiConnection} connection - The JitsiConnection which failed.
|
||||
* @param {string} error - Error.
|
||||
* @param {string} errorMessage - Error message.
|
||||
* @returns {{
|
||||
* type: CONNECTION_FAILED,
|
||||
* connection: JitsiConnection,
|
||||
* error: string,
|
||||
* errorMessage: string
|
||||
* }}
|
||||
* @public
|
||||
*/
|
||||
export function connectionFailed(
|
||||
connection: Object, error: string, errorMessage: string) {
|
||||
return {
|
||||
type: CONNECTION_FAILED,
|
||||
connection,
|
||||
error,
|
||||
errorMessage
|
||||
type: SET_LOCATION_URL,
|
||||
locationURL
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,11 +8,8 @@ import {
|
|||
WEBRTC_NOT_READY,
|
||||
WEBRTC_NOT_SUPPORTED
|
||||
} from '../lib-jitsi-meet';
|
||||
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
|
||||
import { SET_DOMAIN } from './actionTypes';
|
||||
|
||||
declare var APP: Object;
|
||||
declare var config: Object;
|
||||
|
||||
|
@ -20,7 +17,8 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|||
|
||||
export {
|
||||
connectionEstablished,
|
||||
connectionFailed
|
||||
connectionFailed,
|
||||
setLocationURL
|
||||
} from './actions.native.js';
|
||||
|
||||
/**
|
||||
|
@ -106,19 +104,3 @@ export function disconnect() {
|
|||
// app.
|
||||
return () => APP.conference.hangup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets connection domain.
|
||||
*
|
||||
* @param {string} domain - Domain name.
|
||||
* @returns {{
|
||||
* type: SET_DOMAIN,
|
||||
* domain: string
|
||||
* }}
|
||||
*/
|
||||
export function setDomain(domain: string) {
|
||||
return {
|
||||
type: SET_DOMAIN,
|
||||
domain
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/* @flow */
|
||||
|
||||
/**
|
||||
* Returns current domain.
|
||||
*
|
||||
* @param {(Function|Object)} stateOrGetState - Redux getState() method or Redux
|
||||
* state.
|
||||
* @returns {(string|undefined)}
|
||||
*/
|
||||
export function getDomain(stateOrGetState: Function | Object) {
|
||||
const state
|
||||
= typeof stateOrGetState === 'function'
|
||||
? stateOrGetState()
|
||||
: stateOrGetState;
|
||||
const { options } = state['features/base/connection'];
|
||||
let domain;
|
||||
|
||||
try {
|
||||
domain = options.hosts.domain;
|
||||
} catch (e) {
|
||||
// XXX The value of options or any of the properties descending from it
|
||||
// may be undefined at some point in the execution (e.g. on start).
|
||||
// Instead of multiple checks for the undefined value, we just wrap it
|
||||
// in a try-catch block.
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
export * from './actions';
|
||||
export * from './actionTypes';
|
||||
export * from './functions';
|
||||
|
||||
import './reducer';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* @flow */
|
||||
|
||||
import { ReducerRegistry, set } from '../redux';
|
||||
import { assign, ReducerRegistry, set } from '../redux';
|
||||
|
||||
import {
|
||||
CONNECTION_DISCONNECTED,
|
||||
CONNECTION_ESTABLISHED,
|
||||
SET_DOMAIN
|
||||
SET_LOCATION_URL
|
||||
} from './actionTypes';
|
||||
|
||||
/**
|
||||
|
@ -21,8 +21,8 @@ ReducerRegistry.register(
|
|||
case CONNECTION_ESTABLISHED:
|
||||
return _connectionEstablished(state, action);
|
||||
|
||||
case SET_DOMAIN:
|
||||
return _setDomain(state, action);
|
||||
case SET_LOCATION_URL:
|
||||
return _setLocationURL(state, action);
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -38,8 +38,10 @@ ReducerRegistry.register(
|
|||
* @returns {Object} The new state of the feature base/connection after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _connectionDisconnected(state: Object, action: Object) {
|
||||
if (state.connection === action.connection) {
|
||||
function _connectionDisconnected(
|
||||
state: Object,
|
||||
{ connection }: { connection: Object }) {
|
||||
if (state.connection === connection) {
|
||||
return set(state, 'connection', undefined);
|
||||
}
|
||||
|
||||
|
@ -56,13 +58,15 @@ function _connectionDisconnected(state: Object, action: Object) {
|
|||
* @returns {Object} The new state of the feature base/connection after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _connectionEstablished(state: Object, action: Object) {
|
||||
return set(state, 'connection', action.connection);
|
||||
function _connectionEstablished(
|
||||
state: Object,
|
||||
{ connection }: { connection: Object }) {
|
||||
return set(state, 'connection', connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs options to be passed to the constructor of JitsiConnection based
|
||||
* on a specific domain.
|
||||
* Constructs options to be passed to the constructor of {@code JitsiConnection}
|
||||
* based on a specific domain.
|
||||
*
|
||||
* @param {string} domain - The domain with which the returned options are to be
|
||||
* populated.
|
||||
|
@ -105,20 +109,20 @@ function _constructOptions(domain: string) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Reduces a specific Redux action SET_DOMAIN of the feature base/connection.
|
||||
* Reduces a specific redux action {@link SET_LOCATION_URL} of the feature
|
||||
* base/connection.
|
||||
*
|
||||
* @param {Object} state - The Redux state of the feature base/connection.
|
||||
* @param {Action} action - The Redux action SET_DOMAIN to reduce.
|
||||
* @param {Object} state - The redux state of the feature base/connection.
|
||||
* @param {Action} action - The redux action {@code SET_LOCATION_URL} to reduce.
|
||||
* @private
|
||||
* @returns {Object} The new state of the feature base/connection after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _setDomain(state: Object, action: Object) {
|
||||
return {
|
||||
...state,
|
||||
options: {
|
||||
...state.options,
|
||||
..._constructOptions(action.domain)
|
||||
}
|
||||
};
|
||||
function _setLocationURL(
|
||||
state: Object,
|
||||
{ locationURL }: { locationURL: ?URL }) {
|
||||
return assign(state, {
|
||||
locationURL,
|
||||
options: locationURL ? _constructOptions(locationURL.host) : undefined
|
||||
});
|
||||
}
|
||||
|
|
|
@ -52,13 +52,13 @@ export function isFatalJitsiConnectionError(error: string) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads config.js file from remote server.
|
||||
* Loads config.js from a specific remote server.
|
||||
*
|
||||
* @param {string} host - Host where config.js is hosted.
|
||||
* @param {string} path='/config.js' - Relative pah to config.js file.
|
||||
* @param {string} path='config.js' - Relative pah to config.js file.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export function loadConfig(host: string, path: string = '/config.js') {
|
||||
export function loadConfig(host: string, path: string = 'config.js') {
|
||||
let promise;
|
||||
|
||||
if (typeof APP === 'undefined') {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import jwtDecode from 'jwt-decode';
|
||||
|
||||
import { SET_ROOM_URL } from '../base/conference';
|
||||
import { parseURLParams, SET_CONFIG } from '../base/config';
|
||||
import { SET_LOCATION_URL } from '../base/connection';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
import { setJWT } from './actions';
|
||||
|
@ -17,13 +17,13 @@ import { SET_JWT } from './actionTypes';
|
|||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case SET_CONFIG:
|
||||
case SET_ROOM_URL:
|
||||
case SET_LOCATION_URL:
|
||||
// XXX The JSON Web Token (JWT) is not the only piece of state that we
|
||||
// have decided to store in the feature jwt, there is isGuest as well
|
||||
// which depends on the states of the features base/config and jwt. So
|
||||
// the JSON Web Token comes from the room's URL and isGuest needs a
|
||||
// recalculation upon SET_CONFIG as well.
|
||||
return _setConfigOrRoomURL(store, next, action);
|
||||
// the JSON Web Token comes from the conference/room's URL and isGuest
|
||||
// needs a recalculation upon SET_CONFIG as well.
|
||||
return _setConfigOrLocationURL(store, next, action);
|
||||
|
||||
case SET_JWT:
|
||||
return _setJWT(store, next, action);
|
||||
|
@ -34,7 +34,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
|
||||
/**
|
||||
* Notifies the feature jwt that the action {@link SET_CONFIG} or
|
||||
* {@link SET_ROOM_URL} is being dispatched within a specific Redux
|
||||
* {@link SET_LOCATION_URL} is being dispatched within a specific Redux
|
||||
* {@code store}.
|
||||
*
|
||||
* @param {Store} store - The Redux store in which the specified {@code action}
|
||||
|
@ -42,20 +42,20 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
* @param {Dispatch} next - The Redux dispatch function to dispatch the
|
||||
* specified {@code action} to the specified {@code store}.
|
||||
* @param {Action} action - The Redux action {@code SET_CONFIG} or
|
||||
* {@code SET_ROOM_NAME} which is being dispatched in the specified
|
||||
* {@code SET_LOCATION_URL} which is being dispatched in the specified
|
||||
* {@code store}.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _setConfigOrRoomURL({ dispatch, getState }, next, action) {
|
||||
function _setConfigOrLocationURL({ dispatch, getState }, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
const { roomURL } = getState()['features/base/conference'];
|
||||
const { locationURL } = getState()['features/base/connection'];
|
||||
let jwt;
|
||||
|
||||
if (roomURL) {
|
||||
jwt = parseURLParams(roomURL, true, 'search').jwt;
|
||||
if (locationURL) {
|
||||
jwt = parseURLParams(locationURL, true, 'search').jwt;
|
||||
}
|
||||
dispatch(setJWT(jwt));
|
||||
|
||||
|
|
|
@ -47,15 +47,13 @@ ReducerRegistry.register('features/overlay', (state = {}, action) => {
|
|||
* the specified action.
|
||||
* @private
|
||||
*/
|
||||
function _conferenceFailed(state, action) {
|
||||
const error = action.error;
|
||||
|
||||
function _conferenceFailed(state, { error, message }) {
|
||||
if (error === JitsiConferenceErrors.FOCUS_LEFT
|
||||
|| error === JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE) {
|
||||
return assign(state, {
|
||||
haveToReload: true,
|
||||
isNetworkFailure: false,
|
||||
reason: action.errorMessage
|
||||
reason: message
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -84,13 +82,9 @@ function _connectionEstablished(state) {
|
|||
* the specified action.
|
||||
* @private
|
||||
*/
|
||||
function _connectionFailed(state, action) {
|
||||
const error = action.error;
|
||||
|
||||
function _connectionFailed(state, { error, message }) {
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
const errorMessage = action.errorMessage;
|
||||
|
||||
logger.error(`XMPP connection error: ${errorMessage}`);
|
||||
logger.error(`XMPP connection error: ${message}`);
|
||||
|
||||
return assign(state, {
|
||||
haveToReload: true,
|
||||
|
@ -99,7 +93,7 @@ function _connectionFailed(state, action) {
|
|||
// considered a network type of failure.
|
||||
isNetworkFailure:
|
||||
error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR,
|
||||
reason: `xmpp-conn-dropped: ${errorMessage}`
|
||||
reason: `xmpp-conn-dropped: ${message}`
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -12,18 +12,17 @@ import { BEGIN_SHARE_ROOM, END_SHARE_ROOM } from './actionTypes';
|
|||
export function beginShareRoom(roomURL: ?string): Function {
|
||||
return (dispatch, getState) => {
|
||||
if (!roomURL) {
|
||||
const { conference, room } = getState()['features/base/conference'];
|
||||
const { locationURL } = getState()['features/base/connection'];
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
roomURL = _getRoomURL(conference, room);
|
||||
}
|
||||
|
||||
if (roomURL) {
|
||||
dispatch({
|
||||
type: BEGIN_SHARE_ROOM,
|
||||
roomURL
|
||||
});
|
||||
if (locationURL) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
roomURL = locationURL.toString();
|
||||
}
|
||||
}
|
||||
roomURL && dispatch({
|
||||
type: BEGIN_SHARE_ROOM,
|
||||
roomURL
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -47,19 +46,3 @@ export function endShareRoom(roomURL: string, shared: boolean): Object {
|
|||
shared
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public URL of a conference/room.
|
||||
*
|
||||
* @param {JitsiConference} conference - The JitsiConference to share the URL
|
||||
* of.
|
||||
* @param {string} room - The name of the room to share the URL of.
|
||||
* @private
|
||||
* @returns {string|null}
|
||||
*/
|
||||
function _getRoomURL(conference, room) {
|
||||
return (
|
||||
conference
|
||||
&& room
|
||||
&& `https://${conference.connection.options.hosts.domain}/${room}`);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue