Flow, coding style
This commit is contained in:
parent
4c00d39bf2
commit
f53c79ab24
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import JitsiMeetJS, { isAnalyticsEnabled } from '../base/lib-jitsi-meet';
|
||||
import { getJitsiMeetGlobalNS, loadScript } from '../base/util';
|
||||
|
||||
|
@ -13,7 +15,7 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|||
* is being dispatched.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function initAnalytics({ getState }) {
|
||||
export function initAnalytics({ getState }: { getState: Function }) {
|
||||
getJitsiMeetGlobalNS().analyticsHandlers = [];
|
||||
window.analyticsHandlers = []; // Legacy support.
|
||||
|
||||
|
@ -36,12 +38,12 @@ export function initAnalytics({ getState }) {
|
|||
|
||||
_loadHandlers(analyticsScriptUrls, handlerConstructorOptions)
|
||||
.then(handlers => {
|
||||
const permanentProperties = {
|
||||
roomName: getState()['features/base/conference'].room,
|
||||
const state = getState();
|
||||
const permanentProperties: Object = {
|
||||
roomName: state['features/base/conference'].room,
|
||||
userAgent: navigator.userAgent
|
||||
};
|
||||
|
||||
const { group, server } = getState()['features/jwt'];
|
||||
const { group, server } = state['features/jwt'];
|
||||
|
||||
if (server) {
|
||||
permanentProperties.server = server;
|
||||
|
@ -50,13 +52,14 @@ export function initAnalytics({ getState }) {
|
|||
permanentProperties.group = group;
|
||||
}
|
||||
|
||||
// optionally include local deployment information based on
|
||||
// the contents of window.config.deploymentInfo
|
||||
if (config.deploymentInfo) {
|
||||
for (const key in config.deploymentInfo) {
|
||||
if (config.deploymentInfo.hasOwnProperty(key)) {
|
||||
permanentProperties[key]
|
||||
= config.deploymentInfo[key];
|
||||
// Optionally, include local deployment information based on the
|
||||
// contents of window.config.deploymentInfo.
|
||||
const { deploymentInfo } = config;
|
||||
|
||||
if (deploymentInfo) {
|
||||
for (const key in deploymentInfo) {
|
||||
if (deploymentInfo.hasOwnProperty(key)) {
|
||||
permanentProperties[key] = deploymentInfo[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,12 +116,13 @@ function _loadHandlers(scriptURLs, handlerConstructorOptions) {
|
|||
|
||||
if (analyticsHandlers.length === 0) {
|
||||
throw new Error('No analytics handlers available');
|
||||
} else {
|
||||
}
|
||||
|
||||
const handlers = [];
|
||||
|
||||
for (const Handler of analyticsHandlers) {
|
||||
// catch any error while loading to avoid
|
||||
// skipping analytics in case of multiple scripts
|
||||
// Catch any error while loading to avoid skipping analytics in case
|
||||
// of multiple scripts.
|
||||
try {
|
||||
handlers.push(new Handler(handlerConstructorOptions));
|
||||
} catch (error) {
|
||||
|
@ -129,7 +133,5 @@ function _loadHandlers(scriptURLs, handlerConstructorOptions) {
|
|||
logger.debug(`Loaded ${handlers.length} analytics handlers`);
|
||||
|
||||
return handlers;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { Text } from 'react-native';
|
||||
|
@ -79,6 +81,8 @@ class WaitForOwnerDialog extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
_onCancel: () => void;
|
||||
|
||||
/**
|
||||
* Called when the cancel button is clicked.
|
||||
*
|
||||
|
@ -89,6 +93,8 @@ class WaitForOwnerDialog extends Component {
|
|||
this.props.dispatch(cancelWaitForOwner());
|
||||
}
|
||||
|
||||
_onLogin: () => void;
|
||||
|
||||
/**
|
||||
* Called when the OK button is clicked.
|
||||
*
|
||||
|
@ -102,11 +108,11 @@ class WaitForOwnerDialog extends Component {
|
|||
/**
|
||||
* Renders a specific {@code string} which may contain HTML.
|
||||
*
|
||||
* @param {string} html - The {@code string} which may contain HTML to
|
||||
* render.
|
||||
* @param {string|undefined} html - The {@code string} which may
|
||||
* contain HTML to render.
|
||||
* @returns {ReactElement[]|string}
|
||||
*/
|
||||
_renderHTML(html) {
|
||||
_renderHTML(html: ?string) {
|
||||
if (typeof html === 'string') {
|
||||
// At the time of this writing, the specified HTML contains a couple
|
||||
// of spaces one after the other. They do not cause a visible
|
||||
|
@ -164,9 +170,7 @@ class WaitForOwnerDialog extends Component {
|
|||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
const {
|
||||
authRequired
|
||||
} = state['features/base/conference'];
|
||||
const { authRequired } = state['features/base/conference'];
|
||||
|
||||
return {
|
||||
_room: authRequired && authRequired.getName()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { appNavigate } from '../app';
|
||||
import {
|
||||
CONFERENCE_FAILED,
|
||||
|
@ -134,7 +136,8 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
* @param {Object} store - The redux store.
|
||||
* @returns {void}
|
||||
*/
|
||||
function _clearExistingWaitForOwnerTimeout({ getState }) {
|
||||
function _clearExistingWaitForOwnerTimeout(
|
||||
{ getState }: { getState: Function }) {
|
||||
const { waitForOwnerTimeoutID } = getState()['features/authentication'];
|
||||
|
||||
waitForOwnerTimeoutID && clearTimeout(waitForOwnerTimeoutID);
|
||||
|
@ -146,7 +149,7 @@ function _clearExistingWaitForOwnerTimeout({ getState }) {
|
|||
* @param {Object} store - The redux store.
|
||||
* @returns {void}
|
||||
*/
|
||||
function _hideLoginDialog({ dispatch }) {
|
||||
function _hideLoginDialog({ dispatch }: { dispatch: Dispatch<*> }) {
|
||||
dispatch(hideDialog(LoginDialog));
|
||||
}
|
||||
|
||||
|
@ -156,6 +159,6 @@ function _hideLoginDialog({ dispatch }) {
|
|||
* @param {Object} store - The redux store.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function _isWaitingForOwner({ getState }) {
|
||||
function _isWaitingForOwner({ getState }: { getState: Function }) {
|
||||
return Boolean(getState()['features/authentication'].waitForOwnerTimeoutID);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* global APP */
|
||||
// @flow
|
||||
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
|
||||
import { CONNECTION_ESTABLISHED } from '../connection';
|
||||
|
@ -34,6 +35,8 @@ import {
|
|||
_removeLocalTracksFromConference
|
||||
} from './functions';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Implements the middleware of the feature base/conference.
|
||||
*
|
||||
|
@ -299,14 +302,12 @@ function _setLastN(store, next, action) {
|
|||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
function _setReceiveVideoQuality(store, next, action) {
|
||||
const { audioOnly, conference }
|
||||
= store.getState()['features/base/conference'];
|
||||
function _setReceiveVideoQuality({ dispatch, getState }, next, action) {
|
||||
const { audioOnly, conference } = getState()['features/base/conference'];
|
||||
|
||||
conference.setReceiverVideoConstraint(action.receiveVideoQuality);
|
||||
|
||||
if (audioOnly) {
|
||||
store.dispatch(toggleAudioOnly());
|
||||
dispatch(toggleAudioOnly());
|
||||
}
|
||||
|
||||
return next(action);
|
||||
|
@ -321,9 +322,9 @@ function _setReceiveVideoQuality(store, next, action) {
|
|||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function _syncConferenceLocalTracksWithState(store, action) {
|
||||
const state = store.getState()['features/base/conference'];
|
||||
const conference = state.conference;
|
||||
function _syncConferenceLocalTracksWithState({ getState }, action) {
|
||||
const state = getState()['features/base/conference'];
|
||||
const { conference } = state;
|
||||
let promise;
|
||||
|
||||
// XXX The conference may already be in the process of being left, that's
|
||||
|
@ -354,8 +355,8 @@ function _syncConferenceLocalTracksWithState(store, action) {
|
|||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
function _syncReceiveVideoQuality(store, next, action) {
|
||||
const state = store.getState()['features/base/conference'];
|
||||
function _syncReceiveVideoQuality({ getState }, next, action) {
|
||||
const state = getState()['features/base/conference'];
|
||||
|
||||
state.conference.setReceiverVideoConstraint(state.receiveVideoQuality);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { CONNECTION_WILL_CONNECT } from '../connection';
|
||||
import { JitsiConferenceErrors } from '../lib-jitsi-meet';
|
||||
import { assign, ReducerRegistry, set } from '../redux';
|
||||
|
@ -351,7 +353,7 @@ function _setReceiveVideoQuality(state, action) {
|
|||
* reduction of the specified action.
|
||||
*/
|
||||
function _setRoom(state, action) {
|
||||
let room = action.room;
|
||||
let { room } = action;
|
||||
|
||||
if (!isRoomValid(room)) {
|
||||
// Technically, there are multiple values which don't represent valid
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component } from 'react';
|
||||
|
||||
|
@ -28,18 +30,21 @@ export default class AbstractDialog extends Component {
|
|||
dispatch: PropTypes.func
|
||||
};
|
||||
|
||||
_mounted: boolean;
|
||||
|
||||
state = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new {@code AbstractDialog} instance.
|
||||
*
|
||||
* @param {Object} props - The read-only React {@code Component} props with
|
||||
* which the new instance is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
};
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onCancel = this._onCancel.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
this._onSubmitFulfilled = this._onSubmitFulfilled.bind(this);
|
||||
|
@ -66,6 +71,8 @@ export default class AbstractDialog extends Component {
|
|||
this._mounted = false;
|
||||
}
|
||||
|
||||
_onCancel: () => void;
|
||||
|
||||
/**
|
||||
* Dispatches a redux action to hide this dialog when it's canceled.
|
||||
*
|
||||
|
@ -81,19 +88,21 @@ export default class AbstractDialog extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
_onSubmit: (?string) => void;
|
||||
|
||||
/**
|
||||
* Submits this dialog. If the React {@code Component} prop
|
||||
* Submits this {@code Dialog}. If the React {@code Component} prop
|
||||
* {@code onSubmit} is defined, the function that is the value of the prop
|
||||
* is invoked. If the function returns a {@code thenable}, then the
|
||||
* resolution of the {@code thenable} is awaited. If the submission
|
||||
* completes successfully, a redux action will be dispatched to hide this
|
||||
* dialog.
|
||||
*
|
||||
* @private
|
||||
* @param {string} value - The submitted value if any.
|
||||
* @protected
|
||||
* @param {string} [value] - The submitted value if any.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSubmit(value) {
|
||||
_onSubmit(value: ?string) {
|
||||
const { okDisabled, onSubmit } = this.props;
|
||||
|
||||
if (typeof okDisabled === 'undefined' || !okDisabled) {
|
||||
|
@ -125,6 +134,8 @@ export default class AbstractDialog extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
_onSubmitFulfilled: () => void;
|
||||
|
||||
/**
|
||||
* Notifies this {@code AbstractDialog} that it has been submitted
|
||||
* successfully. Dispatches a redux action to hide this dialog after it has
|
||||
|
@ -139,6 +150,8 @@ export default class AbstractDialog extends Component {
|
|||
this.props.dispatch(hideDialog());
|
||||
}
|
||||
|
||||
_onSubmitRejected: () => void;
|
||||
|
||||
/**
|
||||
* Notifies this {@code AbstractDialog} that its submission has failed.
|
||||
*
|
||||
|
|
|
@ -108,14 +108,9 @@ class Dialog extends AbstractDialog {
|
|||
// Secondly, we cannot get Prompt's default behavior anyway
|
||||
// because we've removed Prompt and we're preserving whatever
|
||||
// it's rendered only.
|
||||
return (
|
||||
React.cloneElement(
|
||||
element,
|
||||
/* props */ {
|
||||
return this._cloneElement(element, /* props */ {
|
||||
onRequestClose: this._onCancel
|
||||
},
|
||||
...React.Children.toArray(element.props.children))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (type === TextInput) {
|
||||
|
@ -146,14 +141,9 @@ class Dialog extends AbstractDialog {
|
|||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
React.cloneElement(
|
||||
element,
|
||||
/* props */ {
|
||||
return this._cloneElement(element, /* props */ {
|
||||
style: set(style, _TAG_KEY, undefined)
|
||||
},
|
||||
...React.Children.toArray(element.props.children))
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,6 +153,23 @@ class Dialog extends AbstractDialog {
|
|||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones a specific {@code ReactElement} and adds/merges specific props
|
||||
* into the clone.
|
||||
*
|
||||
* @param {ReactElement} element - The {@code ReactElement} to clone.
|
||||
* @param {Object} props - The props to add/merge into the clone.
|
||||
* @returns {ReactElement} The close of the specified {@code element} with
|
||||
* the specified {@code props} added/merged.
|
||||
*/
|
||||
_cloneElement(element, props) {
|
||||
return (
|
||||
React.cloneElement(
|
||||
element,
|
||||
props,
|
||||
...React.Children.toArray(element.props.children)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep clone of a specific {@code ReactElement} with the results
|
||||
* of calling a specific function on every node of a specific
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { _handleParticipantError } from '../base/conference';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from '../base/media';
|
||||
import {
|
||||
|
@ -16,9 +18,9 @@ import {
|
|||
* @returns {Function}
|
||||
*/
|
||||
export function selectParticipant() {
|
||||
return (dispatch, getState) => {
|
||||
return (dispatch: Dispatch<*>, getState: Function) => {
|
||||
const state = getState();
|
||||
const conference = state['features/base/conference'].conference;
|
||||
const { conference } = state['features/base/conference'];
|
||||
|
||||
if (conference) {
|
||||
const largeVideo = state['features/large-video'];
|
||||
|
@ -51,7 +53,7 @@ export function selectParticipant() {
|
|||
* @returns {Function}
|
||||
*/
|
||||
export function selectParticipantInLargeVideo() {
|
||||
return (dispatch, getState) => {
|
||||
return (dispatch: Dispatch<*>, getState: Function) => {
|
||||
const state = getState();
|
||||
const participantId = _electParticipantInLargeVideo(state);
|
||||
const largeVideo = state['features/large-video'];
|
||||
|
@ -76,7 +78,7 @@ export function selectParticipantInLargeVideo() {
|
|||
* resolution: number
|
||||
* }}
|
||||
*/
|
||||
export function updateKnownLargeVideoResolution(resolution) {
|
||||
export function updateKnownLargeVideoResolution(resolution: number) {
|
||||
return {
|
||||
type: UPDATE_KNOWN_LARGE_VIDEO_RESOLUTION,
|
||||
resolution
|
||||
|
|
|
@ -85,20 +85,21 @@ function _getSymbolDescription(symbol: Symbol) {
|
|||
* apps may listen to such events via the mechanisms provided by the (native)
|
||||
* mobile Jitsi Meet SDK.
|
||||
*
|
||||
* @param {Object} store - The redux store associated with the need to send the
|
||||
* specified event.
|
||||
* @param {Object} store - The redux store.
|
||||
* @param {string} name - The name of the event to send.
|
||||
* @param {Object} data - The details/specifics of the event to send determined
|
||||
* by/associated with the specified {@code name}.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _sendEvent(store: Object, name: string, data: Object) {
|
||||
function _sendEvent(
|
||||
{ getState }: { getState: Function },
|
||||
name: string,
|
||||
data: Object) {
|
||||
// The JavaScript App needs to provide uniquely identifying information
|
||||
// to the native ExternalAPI module so that the latter may match the former
|
||||
// to the native JitsiMeetView which hosts it.
|
||||
const state = store.getState();
|
||||
const { app } = state['features/app'];
|
||||
const { app } = getState()['features/app'];
|
||||
|
||||
if (app) {
|
||||
const { externalAPIScope } = app.props;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { CONFERENCE_FAILED } from '../base/conference';
|
||||
import {
|
||||
CONNECTION_ESTABLISHED,
|
||||
|
@ -140,10 +142,12 @@ function _connectionWillConnect(
|
|||
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||
* the specified action.
|
||||
*/
|
||||
function _mediaPermissionPromptVisibilityChanged(state, action) {
|
||||
function _mediaPermissionPromptVisibilityChanged(
|
||||
state,
|
||||
{ browser, isVisible }) {
|
||||
return assign(state, {
|
||||
browser: action.browser,
|
||||
isMediaPermissionPromptVisible: action.isVisible
|
||||
browser,
|
||||
isMediaPermissionPromptVisible: isVisible
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { setPassword } from '../base/conference';
|
||||
import { hideDialog, openDialog } from '../base/dialog';
|
||||
import { PasswordRequiredPrompt, RoomLockPrompt } from './components';
|
||||
|
@ -9,15 +11,12 @@ import { PasswordRequiredPrompt, RoomLockPrompt } from './components';
|
|||
* if specified or undefined if the current JitsiConference is to be locked.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function beginRoomLockRequest(conference) {
|
||||
return (dispatch, getState) => {
|
||||
export function beginRoomLockRequest(conference: ?Object) {
|
||||
return (dispatch: Function, getState: Function) => {
|
||||
if (typeof conference === 'undefined') {
|
||||
const state = getState();
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
conference = state['features/base/conference'].conference;
|
||||
conference = getState()['features/base/conference'].conference;
|
||||
}
|
||||
|
||||
if (conference) {
|
||||
dispatch(openDialog(RoomLockPrompt, { conference }));
|
||||
}
|
||||
|
@ -33,15 +32,15 @@ export function beginRoomLockRequest(conference) {
|
|||
* the specified conference.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function endRoomLockRequest(conference, password) {
|
||||
return dispatch => {
|
||||
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());
|
||||
};
|
||||
const endRoomLockRequest_ = () => dispatch(hideDialog(RoomLockPrompt));
|
||||
|
||||
setPassword_.then(endRoomLockRequest_, endRoomLockRequest_);
|
||||
};
|
||||
|
@ -59,6 +58,6 @@ export function endRoomLockRequest(conference, password) {
|
|||
* props: PropTypes
|
||||
* }}
|
||||
*/
|
||||
export function _showPasswordDialog(conference) {
|
||||
export function _openPasswordRequiredPrompt(conference: Object) {
|
||||
return openDialog(PasswordRequiredPrompt, { conference });
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -6,35 +8,44 @@ import { setPassword } from '../../base/conference';
|
|||
import { Dialog } from '../../base/dialog';
|
||||
|
||||
/**
|
||||
* Implements a React Component which prompts the user when a password is
|
||||
* required to join a conference.
|
||||
* {@code PasswordRequiredPrompt}'s React {@code Component} prop types.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The {@code JitsiConference} which requires a password.
|
||||
*
|
||||
* @type {JitsiConference}
|
||||
*/
|
||||
conference: { join: Function },
|
||||
dispatch: Dispatch<*>
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements a React {@code Component} which prompts the user when a password
|
||||
* is required to join a conference.
|
||||
*/
|
||||
class PasswordRequiredPrompt extends Component {
|
||||
/**
|
||||
* PasswordRequiredPrompt component's property types.
|
||||
* {@code PasswordRequiredPrompt}'s React {@code Component} prop types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
/**
|
||||
* The JitsiConference which requires a password.
|
||||
*
|
||||
* @type {JitsiConference}
|
||||
*/
|
||||
conference: PropTypes.object,
|
||||
dispatch: PropTypes.func
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new PasswordRequiredPrompt instance.
|
||||
* Initializes a new {@code PasswordRequiredPrompt} instance.
|
||||
*
|
||||
* @param {Object} props - The read-only properties with which the new
|
||||
* instance is to be initialized.
|
||||
* @param {Props} props - The read-only React {@code Component} props with
|
||||
* which the new instance is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onCancel = this._onCancel.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
}
|
||||
|
@ -55,11 +66,14 @@ class PasswordRequiredPrompt extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
_onCancel: () => boolean;
|
||||
|
||||
/**
|
||||
* Notifies this prompt that it has been dismissed by cancel.
|
||||
*
|
||||
* @private
|
||||
* @returns {boolean} True to hide this dialog/prompt; otherwise, false.
|
||||
* @returns {boolean} If this prompt is to be closed/hidden, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
_onCancel() {
|
||||
// XXX The user has canceled this prompt for a password so we are to
|
||||
|
@ -69,16 +83,19 @@ class PasswordRequiredPrompt extends Component {
|
|||
return this._onSubmit(undefined);
|
||||
}
|
||||
|
||||
_onSubmit: (?string) => boolean;
|
||||
|
||||
/**
|
||||
* Notifies this prompt that it has been dismissed by submitting a specific
|
||||
* value.
|
||||
*
|
||||
* @param {string} value - The submitted value.
|
||||
* @param {string|undefined} value - The submitted value.
|
||||
* @private
|
||||
* @returns {boolean} True to hide this dialog/prompt; otherwise, false.
|
||||
* @returns {boolean} If this prompt is to be closed/hidden, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
_onSubmit(value) {
|
||||
const conference = this.props.conference;
|
||||
_onSubmit(value: ?string) {
|
||||
const { conference }: { conference: { join: Function } } = this.props;
|
||||
|
||||
this.props.dispatch(setPassword(conference, conference.join, value));
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import AKFieldText from '@atlaskit/field-text';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
@ -28,6 +30,10 @@ class PasswordRequiredPrompt extends Component {
|
|||
t: PropTypes.func
|
||||
};
|
||||
|
||||
state = {
|
||||
password: ''
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new PasswordRequiredPrompt instance.
|
||||
*
|
||||
|
@ -37,10 +43,7 @@ class PasswordRequiredPrompt extends Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
password: ''
|
||||
};
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onPasswordChanged = this._onPasswordChanged.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
}
|
||||
|
@ -59,7 +62,8 @@ class PasswordRequiredPrompt extends Component {
|
|||
titleKey = 'dialog.passwordRequired'
|
||||
width = 'small'>
|
||||
{ this._renderBody() }
|
||||
</Dialog>);
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,6 +88,8 @@ class PasswordRequiredPrompt extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
_onPasswordChanged: ({ target: { value: * }}) => void;
|
||||
|
||||
/**
|
||||
* Notifies this dialog that password has changed.
|
||||
*
|
||||
|
@ -91,17 +97,19 @@ class PasswordRequiredPrompt extends Component {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onPasswordChanged(event) {
|
||||
_onPasswordChanged({ target: { value } }) {
|
||||
this.setState({
|
||||
password: event.target.value
|
||||
password: value
|
||||
});
|
||||
}
|
||||
|
||||
_onSubmit: () => boolean;
|
||||
|
||||
/**
|
||||
* Dispatches action to submit value from thus dialog.
|
||||
* Dispatches action to submit value from this dialog.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_onSubmit() {
|
||||
const { conference } = this.props;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -29,13 +31,13 @@ class RoomLockPrompt extends Component {
|
|||
/**
|
||||
* Initializes a new RoomLockPrompt instance.
|
||||
*
|
||||
* @param {Object} props - The read-only properties with which the new
|
||||
* @param {Props} props - The read-only properties with which the new
|
||||
* instance is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onCancel = this._onCancel.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
}
|
||||
|
@ -56,6 +58,8 @@ class RoomLockPrompt extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
_onCancel: () => boolean;
|
||||
|
||||
/**
|
||||
* Notifies this prompt that it has been dismissed by cancel.
|
||||
*
|
||||
|
@ -68,17 +72,19 @@ class RoomLockPrompt extends Component {
|
|||
return this._onSubmit(undefined);
|
||||
}
|
||||
|
||||
_onSubmit: (?string) => boolean;
|
||||
|
||||
/**
|
||||
* Notifies this prompt that it has been dismissed by submitting a specific
|
||||
* value.
|
||||
*
|
||||
* @param {string} value - The submitted value.
|
||||
* @param {string|undefined} value - The submitted value.
|
||||
* @private
|
||||
* @returns {boolean} False because we do not want to hide this
|
||||
* dialog/prompt as the hiding will be handled inside endRoomLockRequest
|
||||
* after setting the password is resolved.
|
||||
*/
|
||||
_onSubmit(value) {
|
||||
_onSubmit(value: ?string) {
|
||||
this.props.dispatch(endRoomLockRequest(this.props.conference, value));
|
||||
|
||||
return false; // Do not hide.
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default as RoomLockPrompt } from './RoomLockPrompt';
|
||||
export { default as PasswordRequiredPrompt } from './PasswordRequiredPrompt';
|
||||
export { default as RoomLockPrompt } from './RoomLockPrompt';
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/* global APP */
|
||||
|
||||
import UIEvents from '../../../service/UI/UIEvents';
|
||||
// @flow
|
||||
|
||||
import {
|
||||
CONFERENCE_FAILED,
|
||||
|
@ -9,8 +7,11 @@ import {
|
|||
} from '../base/conference';
|
||||
import { JitsiConferenceErrors } from '../base/lib-jitsi-meet';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import UIEvents from '../../../service/UI/UIEvents';
|
||||
|
||||
import { _showPasswordDialog } from './actions';
|
||||
import { _openPasswordRequiredPrompt } from './actions';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
|
||||
|
@ -27,7 +28,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
const { conference, error } = action;
|
||||
|
||||
if (conference && error === JitsiConferenceErrors.PASSWORD_REQUIRED) {
|
||||
store.dispatch(_showPasswordDialog(conference));
|
||||
store.dispatch(_openPasswordRequiredPrompt(conference));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { appNavigate } from '../app';
|
||||
import { SET_WEBRTC_READY } from '../base/lib-jitsi-meet';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
@ -28,26 +30,25 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
* specified action to the specified store.
|
||||
* @param {Action} action - The Redux action SET_WEBRTC_READY which is being
|
||||
* dispatched in the specified store.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
* @private
|
||||
*/
|
||||
function _setWebRTCReady(store, next, action) {
|
||||
const nextState = next(action);
|
||||
function _setWebRTCReady({ dispatch, getState }, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
// FIXME The feature unsupported-browser needs to notify the app that it may
|
||||
// need to render a different Component at its current location because the
|
||||
// execution enviroment has changed. The current location is not necessarily
|
||||
// available through window.location (e.g. on mobile) but the following
|
||||
// works at the time of this writing.
|
||||
const windowLocation
|
||||
= store.getState()['features/app'].app.getWindowLocation();
|
||||
const windowLocation = getState()['features/app'].app.getWindowLocation();
|
||||
|
||||
if (windowLocation) {
|
||||
const href = windowLocation.href;
|
||||
const { href } = windowLocation;
|
||||
|
||||
href && store.dispatch(appNavigate(href));
|
||||
href && dispatch(appNavigate(href));
|
||||
}
|
||||
|
||||
return nextState;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import { Component } from 'react';
|
||||
|
||||
|
@ -6,6 +8,14 @@ import { isRoomValid } from '../../base/conference';
|
|||
|
||||
import { generateRoomWithoutSeparator } from '../functions';
|
||||
|
||||
/**
|
||||
* {@code AbstractWelcomePage}'s React {@code Component} prop types.
|
||||
*/
|
||||
type Props = {
|
||||
_room: string,
|
||||
dispatch: Dispatch<*>
|
||||
};
|
||||
|
||||
/**
|
||||
* Base (abstract) class for container component rendering the welcome page.
|
||||
*
|
||||
|
@ -22,14 +32,7 @@ export class AbstractWelcomePage extends Component {
|
|||
dispatch: PropTypes.func
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new {@code AbstractWelcomePage} instance.
|
||||
*
|
||||
* @param {Object} props - The React {@code Component} props to initialize
|
||||
* the new {@code AbstractWelcomePage} instance with.
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
_mounted: ?boolean;
|
||||
|
||||
/**
|
||||
* Save room name into component's local state.
|
||||
|
@ -37,23 +40,31 @@ export class AbstractWelcomePage extends Component {
|
|||
* @type {Object}
|
||||
* @property {number|null} animateTimeoutId - Identifier of the letter
|
||||
* animation timeout.
|
||||
* @property {string} generatedRoomname - Automatically generated
|
||||
* room name.
|
||||
* @property {string} generatedRoomname - Automatically generated room name.
|
||||
* @property {string} room - Room name.
|
||||
* @property {string} roomPlaceholder - Room placeholder
|
||||
* that's used as a placeholder for input.
|
||||
* @property {string} roomPlaceholder - Room placeholder that's used as a
|
||||
* placeholder for input.
|
||||
* @property {nubmer|null} updateTimeoutId - Identifier of the timeout
|
||||
* updating the generated room name.
|
||||
*/
|
||||
this.state = {
|
||||
animateTimeoutId: null,
|
||||
state = {
|
||||
animateTimeoutId: undefined,
|
||||
generatedRoomname: '',
|
||||
joining: false,
|
||||
room: '',
|
||||
roomPlaceholder: '',
|
||||
updateTimeoutId: null
|
||||
updateTimeoutId: undefined
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new {@code AbstractWelcomePage} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* the new {@code AbstractWelcomePage} instance with.
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._animateRoomnameChanging
|
||||
= this._animateRoomnameChanging.bind(this);
|
||||
|
@ -77,9 +88,9 @@ export class AbstractWelcomePage extends Component {
|
|||
* before this mounted component receives new props.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @param {Object} nextProps - New props component will receive.
|
||||
* @param {Props} nextProps - New props component will receive.
|
||||
*/
|
||||
componentWillReceiveProps(nextProps) {
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
this.setState({ room: nextProps._room });
|
||||
}
|
||||
|
||||
|
@ -94,6 +105,8 @@ export class AbstractWelcomePage extends Component {
|
|||
this._mounted = false;
|
||||
}
|
||||
|
||||
_animateRoomnameChanging: (string) => void;
|
||||
|
||||
/**
|
||||
* Animates the changing of the room name.
|
||||
*
|
||||
|
@ -102,8 +115,8 @@ export class AbstractWelcomePage extends Component {
|
|||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_animateRoomnameChanging(word) {
|
||||
let animateTimeoutId = null;
|
||||
_animateRoomnameChanging(word: string) {
|
||||
let animateTimeoutId;
|
||||
const roomPlaceholder = this.state.roomPlaceholder + word.substr(0, 1);
|
||||
|
||||
if (word.length > 1) {
|
||||
|
@ -115,7 +128,6 @@ export class AbstractWelcomePage extends Component {
|
|||
},
|
||||
70);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
animateTimeoutId,
|
||||
roomPlaceholder
|
||||
|
@ -145,6 +157,8 @@ export class AbstractWelcomePage extends Component {
|
|||
return this.state.joining || !isRoomValid(this.state.room);
|
||||
}
|
||||
|
||||
_onJoin: () => void;
|
||||
|
||||
/**
|
||||
* Handles joining. Either by clicking on 'Join' button
|
||||
* or by pressing 'Enter' in room name input field.
|
||||
|
@ -160,15 +174,16 @@ export class AbstractWelcomePage extends Component {
|
|||
|
||||
// By the time the Promise of appNavigate settles, this component
|
||||
// may have already been unmounted.
|
||||
const onAppNavigateSettled = () => {
|
||||
this._mounted && this.setState({ joining: false });
|
||||
};
|
||||
const onAppNavigateSettled
|
||||
= () => this._mounted && this.setState({ joining: false });
|
||||
|
||||
this.props.dispatch(appNavigate(room))
|
||||
.then(onAppNavigateSettled, onAppNavigateSettled);
|
||||
}
|
||||
}
|
||||
|
||||
_onRoomChange: (string) => void;
|
||||
|
||||
/**
|
||||
* Handles 'change' event for the room name text input field.
|
||||
*
|
||||
|
@ -177,10 +192,12 @@ export class AbstractWelcomePage extends Component {
|
|||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_onRoomChange(value) {
|
||||
_onRoomChange(value: string) {
|
||||
this.setState({ room: value });
|
||||
}
|
||||
|
||||
_updateRoomname: () => void;
|
||||
|
||||
/**
|
||||
* Triggers the generation of a new room name and initiates an animation of
|
||||
* its changing.
|
||||
|
@ -214,7 +231,7 @@ export class AbstractWelcomePage extends Component {
|
|||
* _room: string
|
||||
* }}
|
||||
*/
|
||||
export function _mapStateToProps(state) {
|
||||
export function _mapStateToProps(state: Object) {
|
||||
return {
|
||||
_room: state['features/base/conference'].room
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue