Flow, coding style
This commit is contained in:
parent
d4d2cb4aad
commit
2eb36c4053
|
@ -8,16 +8,6 @@
|
|||
*/
|
||||
export const CANCEL_LOGIN = Symbol('CANCEL_LOGIN');
|
||||
|
||||
/**
|
||||
* The type of (redux) action which signals that the {@link WaitForOwnerDialog}
|
||||
* has been canceled.
|
||||
*
|
||||
* {
|
||||
* type: CANCEL_WAIT_FOR_OWNER
|
||||
* }
|
||||
*/
|
||||
export const CANCEL_WAIT_FOR_OWNER = Symbol('CANCEL_WAIT_FOR_OWNER');
|
||||
|
||||
/**
|
||||
* The type of (redux) action which signals that the cyclic operation of waiting
|
||||
* for conference owner has been aborted.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import { appNavigate } from '../app';
|
||||
import { checkIfCanJoin } from '../base/conference';
|
||||
import { openDialog } from '../base/dialog';
|
||||
|
||||
import {
|
||||
CANCEL_LOGIN,
|
||||
CANCEL_WAIT_FOR_OWNER,
|
||||
STOP_WAIT_FOR_OWNER,
|
||||
UPGRADE_ROLE_FINISHED,
|
||||
UPGRADE_ROLE_STARTED,
|
||||
|
@ -25,7 +25,7 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|||
* @param {string} password - The XMPP user's password.
|
||||
* @param {JitsiConference} conference - The conference for which the local
|
||||
* participant's role will be upgraded.
|
||||
* @returns {function({ dispatch: Dispatch, getState: Function })}
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function authenticateAndUpgradeRole(
|
||||
id: string,
|
||||
|
@ -79,13 +79,12 @@ export function cancelLogin() {
|
|||
/**
|
||||
* Cancels {@link WaitForOwnerDialog}. Will navigate back to the welcome page.
|
||||
*
|
||||
* @returns {{
|
||||
* type: CANCEL_WAIT_FOR_OWNER
|
||||
* }}
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function cancelWaitForOwner() {
|
||||
return {
|
||||
type: CANCEL_WAIT_FOR_OWNER
|
||||
return (dispatch: Dispatch<*>) => {
|
||||
dispatch(stopWaitForOwner());
|
||||
dispatch(appNavigate(undefined));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -197,7 +196,7 @@ function _upgradeRoleStarted(thenableWithCancel) {
|
|||
* start the process of "waiting for the owner" by periodically trying to join
|
||||
* the room every five seconds.
|
||||
*
|
||||
* @returns {function({ dispatch: Dispatch })}
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function waitForOwner() {
|
||||
return (dispatch: Dispatch) =>
|
||||
|
|
|
@ -22,7 +22,6 @@ import {
|
|||
} from './actions';
|
||||
import {
|
||||
CANCEL_LOGIN,
|
||||
CANCEL_WAIT_FOR_OWNER,
|
||||
STOP_WAIT_FOR_OWNER,
|
||||
WAIT_FOR_OWNER
|
||||
} from './actionTypes';
|
||||
|
@ -40,8 +39,8 @@ import { LoginDialog, WaitForOwnerDialog } from './components';
|
|||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case CANCEL_LOGIN: {
|
||||
const { thenableWithCancel }
|
||||
= store.getState()['features/authentication'];
|
||||
const { dispatch, getState } = store;
|
||||
const { thenableWithCancel } = getState()['features/authentication'];
|
||||
|
||||
thenableWithCancel && thenableWithCancel.cancel();
|
||||
|
||||
|
@ -53,27 +52,18 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
// Instead of hiding show the new one.
|
||||
const result = next(action);
|
||||
|
||||
store.dispatch(_openWaitForOwnerDialog());
|
||||
dispatch(_openWaitForOwnerDialog());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Go back to the app's entry point.
|
||||
_hideLoginDialog(store);
|
||||
store.dispatch(appNavigate(undefined));
|
||||
dispatch(appNavigate(undefined));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CANCEL_WAIT_FOR_OWNER: {
|
||||
const result = next(action);
|
||||
|
||||
store.dispatch(stopWaitForOwner());
|
||||
store.dispatch(appNavigate(undefined));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case CONFERENCE_FAILED:
|
||||
if (action.error.name
|
||||
=== JitsiConferenceErrors.AUTHENTICATION_REQUIRED) {
|
||||
|
|
|
@ -71,6 +71,15 @@ export default class AbstractDialog extends Component {
|
|||
this._mounted = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a redux action to hide this dialog.
|
||||
*
|
||||
* @returns {*} The return value of {@link hideDialog}.
|
||||
*/
|
||||
_hide() {
|
||||
return this.props.dispatch(hideDialog());
|
||||
}
|
||||
|
||||
_onCancel: () => void;
|
||||
|
||||
/**
|
||||
|
@ -84,7 +93,7 @@ export default class AbstractDialog extends Component {
|
|||
|
||||
if ((typeof cancelDisabled === 'undefined' || !cancelDisabled)
|
||||
&& (!onCancel || onCancel())) {
|
||||
this.props.dispatch(hideDialog());
|
||||
this._hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +156,7 @@ export default class AbstractDialog extends Component {
|
|||
_onSubmitFulfilled() {
|
||||
this._mounted && this.setState({ submitting: false });
|
||||
|
||||
this.props.dispatch(hideDialog());
|
||||
this._hide();
|
||||
}
|
||||
|
||||
_onSubmitRejected: () => void;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export { default as Container } from './Container';
|
||||
export { default as MultiSelectAutocomplete } from './MultiSelectAutocomplete';
|
||||
export { default as Text } from './Text';
|
||||
export { default as Watermarks } from './Watermarks';
|
||||
export { default as MultiSelectAutocomplete } from './MultiSelectAutocomplete';
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import Tabs from '@atlaskit/tabs';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
@ -15,7 +17,12 @@ const THUMBNAIL_SIZE = {
|
|||
};
|
||||
const UPDATE_INTERVAL = 1000;
|
||||
|
||||
const TAB_CONFIGURATIONS = [
|
||||
type TabConfiguration = {
|
||||
defaultSelected?: boolean,
|
||||
label: string,
|
||||
type: string
|
||||
};
|
||||
const TAB_CONFIGURATIONS: Array<TabConfiguration> = [
|
||||
{
|
||||
/**
|
||||
* The indicator which determines whether this tab configuration is
|
||||
|
@ -83,6 +90,14 @@ class DesktopPicker extends Component {
|
|||
t: PropTypes.func
|
||||
};
|
||||
|
||||
_poller = null;
|
||||
|
||||
state = {
|
||||
selectedSource: {},
|
||||
tabsToPopulate: [],
|
||||
typesToFetch: []
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new DesktopPicker instance.
|
||||
*
|
||||
|
@ -92,13 +107,7 @@ class DesktopPicker extends Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
selectedSource: {},
|
||||
tabsToPopulate: [],
|
||||
typesToFetch: []
|
||||
};
|
||||
|
||||
this._poller = null;
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onCloseModal = this._onCloseModal.bind(this);
|
||||
this._onPreviewClick = this._onPreviewClick.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
|
@ -175,12 +184,14 @@ class DesktopPicker extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
_onCloseModal: (?string, string) => void;
|
||||
|
||||
/**
|
||||
* Dispatches an action to hide the DesktopPicker and invokes the passed in
|
||||
* callback with a selectedSource, if any.
|
||||
*
|
||||
* @param {string} id - The id of the DesktopCapturerSource to pass into the
|
||||
* onSourceChoose callback.
|
||||
* @param {string} [id] - The id of the DesktopCapturerSource to pass into
|
||||
* the onSourceChoose callback.
|
||||
* @param {string} type - The type of the DesktopCapturerSource to pass into
|
||||
* the onSourceChoose callback.
|
||||
* @returns {void}
|
||||
|
@ -190,6 +201,8 @@ class DesktopPicker extends Component {
|
|||
this.props.dispatch(hideDialog());
|
||||
}
|
||||
|
||||
_onPreviewClick: (string, string) => void;
|
||||
|
||||
/**
|
||||
* Sets the currently selected DesktopCapturerSource.
|
||||
*
|
||||
|
@ -206,6 +219,27 @@ class DesktopPicker extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changing of allowed desktop sharing source types.
|
||||
*
|
||||
* @param {Array<string>} desktopSharingSourceTypes - The types that will be
|
||||
* fetched and displayed.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSourceTypesConfigChanged(desktopSharingSourceTypes = []) {
|
||||
const tabsToPopulate
|
||||
= TAB_CONFIGURATIONS.filter(({ type }) =>
|
||||
desktopSharingSourceTypes.includes(type)
|
||||
&& VALID_TYPES.includes(type));
|
||||
|
||||
this.setState({
|
||||
tabsToPopulate,
|
||||
typesToFetch: tabsToPopulate.map(c => c.type)
|
||||
});
|
||||
}
|
||||
|
||||
_onSubmit: () => void;
|
||||
|
||||
/**
|
||||
* Request to close the modal and execute callbacks with the selected source
|
||||
* id.
|
||||
|
@ -268,24 +302,7 @@ class DesktopPicker extends Component {
|
|||
this._poller = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changing of allowed desktop sharing source types.
|
||||
*
|
||||
* @param {Array<string>} desktopSharingSourceTypes - The types that will be
|
||||
* fetched and displayed.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSourceTypesConfigChanged(desktopSharingSourceTypes = []) {
|
||||
const tabsToPopulate = TAB_CONFIGURATIONS.filter(
|
||||
c => desktopSharingSourceTypes.includes(c.type)
|
||||
&& VALID_TYPES.includes(c.type)
|
||||
);
|
||||
|
||||
this.setState({
|
||||
tabsToPopulate,
|
||||
typesToFetch: tabsToPopulate.map(c => c.type)
|
||||
});
|
||||
}
|
||||
_updateSources: () => void;
|
||||
|
||||
/**
|
||||
* Dispatches an action to get currently available DesktopCapturerSources.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import Avatar from '@atlaskit/avatar';
|
||||
import InlineMessage from '@atlaskit/inline-message';
|
||||
import { Immutable } from 'nuclear-js';
|
||||
|
@ -8,8 +10,7 @@ import { connect } from 'react-redux';
|
|||
import { getInviteURL } from '../../base/connection';
|
||||
import { Dialog, hideDialog } from '../../base/dialog';
|
||||
import { translate } from '../../base/i18n';
|
||||
import MultiSelectAutocomplete
|
||||
from '../../base/react/components/web/MultiSelectAutocomplete';
|
||||
import { MultiSelectAutocomplete } from '../../base/react';
|
||||
|
||||
import { invitePeople, inviteRooms, searchPeople } from '../functions';
|
||||
|
||||
|
@ -67,6 +68,54 @@ class AddPeopleDialog extends Component {
|
|||
t: PropTypes.func
|
||||
};
|
||||
|
||||
_multiselect = null;
|
||||
|
||||
_resourceClient = {
|
||||
makeQuery: text => {
|
||||
const {
|
||||
_jwt,
|
||||
_peopleSearchQueryTypes,
|
||||
_peopleSearchUrl
|
||||
} = this.props; // eslint-disable-line no-invalid-this
|
||||
|
||||
return (
|
||||
searchPeople(
|
||||
_peopleSearchUrl,
|
||||
_jwt,
|
||||
text,
|
||||
_peopleSearchQueryTypes));
|
||||
},
|
||||
|
||||
parseResults: response => response.map(user => {
|
||||
return {
|
||||
content: user.name,
|
||||
elemBefore: <Avatar
|
||||
size = 'medium'
|
||||
src = { user.avatar } />,
|
||||
item: user,
|
||||
value: user.id
|
||||
};
|
||||
})
|
||||
};
|
||||
|
||||
state = {
|
||||
/**
|
||||
* Indicating that an error occurred when adding people to the call.
|
||||
*/
|
||||
addToCallError: false,
|
||||
|
||||
/**
|
||||
* Indicating that we're currently adding the new people to the
|
||||
* call.
|
||||
*/
|
||||
addToCallInProgress: false,
|
||||
|
||||
/**
|
||||
* The list of invite items.
|
||||
*/
|
||||
inviteItems: new Immutable.List()
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new {@code AddPeopleDialog} instance.
|
||||
*
|
||||
|
@ -76,56 +125,7 @@ class AddPeopleDialog extends Component {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
/**
|
||||
* Indicating that an error occurred when adding people to the call.
|
||||
*/
|
||||
addToCallError: false,
|
||||
|
||||
/**
|
||||
* Indicating that we're currently adding the new people to the
|
||||
* call.
|
||||
*/
|
||||
addToCallInProgress: false,
|
||||
|
||||
/**
|
||||
* The list of invite items.
|
||||
*/
|
||||
inviteItems: new Immutable.List()
|
||||
};
|
||||
|
||||
this._multiselect = null;
|
||||
this._resourceClient = {
|
||||
makeQuery: text => {
|
||||
const {
|
||||
_jwt,
|
||||
_peopleSearchQueryTypes,
|
||||
_peopleSearchUrl
|
||||
} = this.props;
|
||||
|
||||
return searchPeople(
|
||||
_peopleSearchUrl,
|
||||
_jwt,
|
||||
text,
|
||||
_peopleSearchQueryTypes
|
||||
);
|
||||
},
|
||||
parseResults: response => response.map(user => {
|
||||
const avatar = ( // eslint-disable-line no-extra-parens
|
||||
<Avatar
|
||||
size = 'medium'
|
||||
src = { user.avatar } />
|
||||
);
|
||||
|
||||
return {
|
||||
content: user.name,
|
||||
value: user.id,
|
||||
elemBefore: avatar,
|
||||
item: user
|
||||
};
|
||||
})
|
||||
};
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._isAddDisabled = this._isAddDisabled.bind(this);
|
||||
this._onSelectionChange = this._onSelectionChange.bind(this);
|
||||
this._onSubmit = this._onSubmit.bind(this);
|
||||
|
@ -144,9 +144,9 @@ class AddPeopleDialog extends Component {
|
|||
* invite.
|
||||
*/
|
||||
if (prevState.addToCallError
|
||||
&& !this.state.addToCallInProgress
|
||||
&& !this.state.addToCallError
|
||||
&& this._multiselect) {
|
||||
&& !this.state.addToCallInProgress
|
||||
&& !this.state.addToCallError
|
||||
&& this._multiselect) {
|
||||
this._multiselect.clear();
|
||||
}
|
||||
}
|
||||
|
@ -169,44 +169,22 @@ class AddPeopleDialog extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the input form.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
* @private
|
||||
*/
|
||||
_renderUserInputForm() {
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<div className = 'add-people-form-wrap'>
|
||||
{ this._renderErrorMessage() }
|
||||
<MultiSelectAutocomplete
|
||||
isDisabled
|
||||
= { this.state.addToCallInProgress || false }
|
||||
noMatchesFound = { t('addPeople.noResults') }
|
||||
onSelectionChange = { this._onSelectionChange }
|
||||
placeholder = { t('addPeople.searchPlaceholder') }
|
||||
ref = { this._setMultiSelectElement }
|
||||
resourceClient = { this._resourceClient }
|
||||
shouldFitContainer = { true }
|
||||
shouldFocus = { true } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
_isAddDisabled: () => boolean;
|
||||
|
||||
/**
|
||||
* Indicates if the Add button should be disabled.
|
||||
*
|
||||
* @private
|
||||
* @returns {boolean} - True to indicate that the Add button should
|
||||
* be disabled, false otherwise.
|
||||
* @private
|
||||
*/
|
||||
_isAddDisabled() {
|
||||
return !this.state.inviteItems.length
|
||||
|| this.state.addToCallInProgress;
|
||||
}
|
||||
|
||||
_onSelectionChange: (Map<*, *>) => void;
|
||||
|
||||
/**
|
||||
* Handles a selection change.
|
||||
*
|
||||
|
@ -222,6 +200,8 @@ class AddPeopleDialog extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
_onSubmit: () => void;
|
||||
|
||||
/**
|
||||
* Handles the submit button action.
|
||||
*
|
||||
|
@ -245,27 +225,28 @@ class AddPeopleDialog extends Component {
|
|||
this.props._inviteUrl,
|
||||
this.props._jwt,
|
||||
this.state.inviteItems.filter(i => i.type === 'user'))
|
||||
.then(() => {
|
||||
this.setState({
|
||||
addToCallInProgress: false
|
||||
});
|
||||
.then(
|
||||
/* onFulfilled */ () => {
|
||||
this.setState({
|
||||
addToCallInProgress: false
|
||||
});
|
||||
|
||||
this.props.hideDialog();
|
||||
})
|
||||
.catch(() => {
|
||||
this.setState({
|
||||
addToCallInProgress: false,
|
||||
addToCallError: true
|
||||
this.props.hideDialog();
|
||||
},
|
||||
/* onRejected */ () => {
|
||||
this.setState({
|
||||
addToCallInProgress: false,
|
||||
addToCallError: true
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the error message if the add doesn't succeed.
|
||||
*
|
||||
* @returns {ReactElement|null}
|
||||
* @private
|
||||
* @returns {ReactElement|null}
|
||||
*/
|
||||
_renderErrorMessage() {
|
||||
if (!this.state.addToCallError) {
|
||||
|
@ -304,6 +285,34 @@ class AddPeopleDialog extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the input form.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderUserInputForm() {
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
<div className = 'add-people-form-wrap'>
|
||||
{ this._renderErrorMessage() }
|
||||
<MultiSelectAutocomplete
|
||||
isDisabled
|
||||
= { this.state.addToCallInProgress || false }
|
||||
noMatchesFound = { t('addPeople.noResults') }
|
||||
onSelectionChange = { this._onSelectionChange }
|
||||
placeholder = { t('addPeople.searchPlaceholder') }
|
||||
ref = { this._setMultiSelectElement }
|
||||
resourceClient = { this._resourceClient }
|
||||
shouldFitContainer = { true }
|
||||
shouldFocus = { true } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_setMultiSelectElement: (Object) => void;
|
||||
|
||||
/**
|
||||
* Sets the instance variable for the multi select component
|
||||
* element so it can be accessed directly.
|
||||
|
@ -338,13 +347,13 @@ function _mapStateToProps(state) {
|
|||
|
||||
return {
|
||||
_conference: conference,
|
||||
_jwt: state['features/jwt'].jwt,
|
||||
_inviteUrl: getInviteURL(state),
|
||||
_inviteServiceUrl: inviteServiceUrl,
|
||||
_inviteUrl: getInviteURL(state),
|
||||
_jwt: state['features/jwt'].jwt,
|
||||
_peopleSearchQueryTypes: peopleSearchQueryTypes,
|
||||
_peopleSearchUrl: peopleSearchUrl
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(
|
||||
connect(_mapStateToProps, { hideDialog })(AddPeopleDialog));
|
||||
export default translate(connect(_mapStateToProps, { hideDialog })(
|
||||
AddPeopleDialog));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import { NativeModules } from 'react-native';
|
||||
import uuid from 'uuid';
|
||||
|
@ -238,9 +238,9 @@ function _onPerformEndCallAction({ callUUID }) {
|
|||
const conference = getCurrentConference(getState);
|
||||
|
||||
if (conference && conference.callUUID === callUUID) {
|
||||
// We arrive here when a call is ended by the system, for
|
||||
// example when another incoming call is received and the user
|
||||
// selects "End & Accept".
|
||||
// We arrive here when a call is ended by the system, for example, when
|
||||
// another incoming call is received and the user selects "End &
|
||||
// Accept".
|
||||
delete conference.callUUID;
|
||||
dispatch(appNavigate(undefined));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue