diff --git a/react/features/always-on-top/AlwaysOnTop.js b/react/features/always-on-top/AlwaysOnTop.js index 3575374bd..8b0e77dec 100644 --- a/react/features/always-on-top/AlwaysOnTop.js +++ b/react/features/always-on-top/AlwaysOnTop.js @@ -1,3 +1,5 @@ +// @flow + import React, { Component } from 'react'; import StatelessToolbar from '../toolbox/components/StatelessToolbar'; @@ -6,15 +8,10 @@ import StatelessToolbarButton const { api } = window.alwaysOnTop; -/** - * The timeout in ms for hidding the toolbar. - */ -const TOOLBAR_TIMEOUT = 4000; - /** * Map with toolbar button descriptors. */ -const toolbarButtons = { +const TOOLBAR_BUTTONS = { /** * The descriptor of the camera toolbar button. */ @@ -54,15 +51,20 @@ const toolbarButtons = { }; /** - * Defines the state for AlwaysOnTop component. + * The timeout in ms for hidding the toolbar. */ -type AlwaysOnTopState = { - visible: boolean, - audioMuted: boolean, - videoMuted: boolean, +const TOOLBAR_TIMEOUT = 4000; + +/** + * The type of the React {@code Component} state of {@link FeedbackButton}. + */ +type State = { audioAvailable: boolean, - videoAvailable: boolean -} + audioMuted: boolean, + videoAvailable: boolean, + videoMuted: boolean, + visible: boolean +}; /** * Represents the always on top page. @@ -70,14 +72,16 @@ type AlwaysOnTopState = { * @class AlwaysOnTop * @extends Component */ -export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { +export default class AlwaysOnTop extends Component<*, State> { + _hovered: boolean; + /** * Initializes new AlwaysOnTop instance. * - * @param {Object} props - The read-only properties with which the new - * instance is to be initialized. + * @param {*} props - The read-only properties with which the new instance + * is to be initialized. */ - constructor(props) { + constructor(props: *) { super(props); this.state = { @@ -88,19 +92,20 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { videoAvailable: false }; - this._hovered = false; - + // Bind event handlers so they are only bound once per instance. this._audioAvailabilityListener = this._audioAvailabilityListener.bind(this); this._audioMutedListener = this._audioMutedListener.bind(this); this._mouseMove = this._mouseMove.bind(this); - this._onMouseOver = this._onMouseOver.bind(this); this._onMouseOut = this._onMouseOut.bind(this); + this._onMouseOver = this._onMouseOver.bind(this); this._videoAvailabilityListener = this._videoAvailabilityListener.bind(this); this._videoMutedListener = this._videoMutedListener.bind(this); } + _audioAvailabilityListener: ({ available: boolean }) => void; + /** * Handles audio available api events. * @@ -111,6 +116,8 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { this.setState({ audioAvailable: available }); } + _audioMutedListener: ({ muted: boolean }) => void; + /** * Handles audio muted api events. * @@ -137,6 +144,8 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { }, TOOLBAR_TIMEOUT); } + _mouseMove: () => void; + /** * Handles mouse move events. * @@ -148,14 +157,7 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { } } - /** - * Toolbar mouse over handler. - * - * @returns {void} - */ - _onMouseOver() { - this._hovered = true; - } + _onMouseOut: () => void; /** * Toolbar mouse out handler. @@ -166,6 +168,19 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { this._hovered = false; } + _onMouseOver: () => void; + + /** + * Toolbar mouse over handler. + * + * @returns {void} + */ + _onMouseOver() { + this._hovered = true; + } + + _videoAvailabilityListener: ({ available: boolean }) => void; + /** * Handles audio available api events. * @@ -176,6 +191,8 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { this.setState({ videoAvailable: available }); } + _videoMutedListener: ({ muted: boolean }) => void; + /** * Handles video muted api events. * @@ -248,7 +265,7 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { * @inheritdoc * @returns {void} */ - componentWillUpdate(nextProps, nextState) { + componentWillUpdate(nextProps: *, nextState: State) { if (!this.state.visible && nextState.visible) { this._hideToolbarAfterTimeout(); } @@ -271,9 +288,15 @@ export default class AlwaysOnTop extends Component<*, AlwaysOnTopState> { onMouseOut = { this._onMouseOut } onMouseOver = { this._onMouseOver }> { - Object.entries(toolbarButtons).map(([ key, button ]) => { + Object.entries(TOOLBAR_BUTTONS).map(([ key, button ]) => { + // XXX The following silences a couple of flow errors: + if (button === null || typeof button !== 'object') { + return null; + } + const { onClick } = button; - let enabled = false, toggled = false; + let enabled = false; + let toggled = false; switch (key) { case 'microphone': diff --git a/react/features/authentication/actions.js b/react/features/authentication/actions.js index 396bb994f..f58461f20 100644 --- a/react/features/authentication/actions.js +++ b/react/features/authentication/actions.js @@ -71,6 +71,9 @@ export function authenticateAndUpgradeRole( * }} */ export function cancelLogin() { + // FIXME Like cancelWaitForOwner, dispatch conferenceLeft to notify the + // external-api. + return { type: CANCEL_LOGIN }; diff --git a/react/features/authentication/components/LoginDialog.native.js b/react/features/authentication/components/LoginDialog.native.js index 103ec7ae8..cf14f815f 100644 --- a/react/features/authentication/components/LoginDialog.native.js +++ b/react/features/authentication/components/LoginDialog.native.js @@ -226,7 +226,7 @@ class LoginDialog extends Component { */ _onLogin() { const { _conference: conference, dispatch } = this.props; - const { username, password } = this.state; + const { password, username } = this.state; const jid = toJid(username, this.props._configHosts); let r; diff --git a/react/features/authentication/components/WaitForOwnerDialog.native.js b/react/features/authentication/components/WaitForOwnerDialog.native.js index ed0b088ca..5947e13e1 100644 --- a/react/features/authentication/components/WaitForOwnerDialog.native.js +++ b/react/features/authentication/components/WaitForOwnerDialog.native.js @@ -11,14 +11,14 @@ import { cancelWaitForOwner, _openLoginDialog } from '../actions'; import styles from './styles'; /** - * WaitForOwnerDialog component's property types. + * The type of the React {@code Component} props of {@link WaitForOwnerDialog}. */ -type WaitForOwnerDialogPropTypes = { +type Props = { /** * The name of the conference room (without the domain part). */ - _room: String, + _room: string, /** * Redux store dispatch function. @@ -37,7 +37,7 @@ type WaitForOwnerDialogPropTypes = { * * See {@link LoginDialog} description for more details. */ -class WaitForOwnerDialog extends Component { +class WaitForOwnerDialog extends Component { /** * Initializes a new WaitForWonderDialog instance. * diff --git a/react/features/authentication/middleware.js b/react/features/authentication/middleware.js index 2cb748e21..12ea592c6 100644 --- a/react/features/authentication/middleware.js +++ b/react/features/authentication/middleware.js @@ -59,6 +59,10 @@ MiddlewareRegistry.register(store => next => action => { // Go back to the app's entry point. _hideLoginDialog(store); + + // FIXME Like cancelWaitForOwner, dispatch conferenceLeft to notify + // the external-api. + dispatch(appNavigate(undefined)); } break; diff --git a/react/features/base/dialog/components/AbstractDialog.js b/react/features/base/dialog/components/AbstractDialog.js index 993e740ff..4d9bfa562 100644 --- a/react/features/base/dialog/components/AbstractDialog.js +++ b/react/features/base/dialog/components/AbstractDialog.js @@ -1,45 +1,36 @@ // @flow -import * as React from 'react'; +import { Component } from 'react'; import { hideDialog } from '../actions'; -import { DialogPropTypes } from '../constants'; +import type { DialogProps } from '../constants'; /** - * Defines the property types for AbstractDialog. + * The type of the React {@code Component} props of {@link AbstractDialog}. */ -export type AbstractDialogPropTypes = { - ...DialogPropTypes, - - /** - * The React {@code Component} children of {@code AbstractDialog} - * which represents the dialog's body. - */ - children: React.Node, +export type Props = { + ...DialogProps, /** * Used to show/hide the dialog on cancel. */ dispatch: Dispatch<*> -} +}; /** - * Defines the state for AbstractDialog. + * The type of the React {@code Component} state of {@link AbstractDialog}. */ -type AbstractDialogState = { - submitting: boolean -} +export type State = { + submitting: ?boolean +}; /** * An abstract implementation of a dialog on Web/React and mobile/react-native. */ -export default class AbstractDialog - extends React.Component { - _mounted: boolean; +export default class AbstractDialog

+ extends Component { - state = { - submitting: false - }; + _mounted: boolean; /** * Initializes a new {@code AbstractDialog} instance. @@ -47,7 +38,7 @@ export default class AbstractDialog * @param {Object} props - The read-only React {@code Component} props with * which the new instance is to be initialized. */ - constructor(props: Object) { + constructor(props: P) { super(props); // Bind event handlers so they are only bound once per instance. diff --git a/react/features/base/dialog/components/Dialog.native.js b/react/features/base/dialog/components/Dialog.native.js index 1ecc0312b..501396d46 100644 --- a/react/features/base/dialog/components/Dialog.native.js +++ b/react/features/base/dialog/components/Dialog.native.js @@ -1,3 +1,6 @@ +// @flow + +import _ from 'lodash'; import React from 'react'; import { Modal, StyleSheet, TextInput } from 'react-native'; import Prompt from 'react-native-prompt'; @@ -7,7 +10,11 @@ import { translate } from '../../i18n'; import { LoadingIndicator } from '../../react'; import { set } from '../../redux'; -import AbstractDialog, { AbstractDialogPropTypes } from './AbstractDialog'; +import AbstractDialog from './AbstractDialog'; +import type { + Props as AbstractDialogProps, + State as AbstractDialogState +} from './AbstractDialog'; import { dialog as styles } from './styles'; /** @@ -27,21 +34,24 @@ const _SUBMIT_TEXT_TAG_VALUE = '_SUBMIT_TEXT_TAG_VALUE'; const _TAG_KEY = '_TAG_KEY'; /** - * {@code Dialog}'s React {@code Component} prop types. + * The type of the React {@code Component} props of {@link Dialog}. */ -type DialogPropTypes = { - ...AbstractDialogPropTypes, +type Props = { + ...AbstractDialogProps, /** * I18n key to put as body title. */ - bodyKey: String -} + bodyKey: String, + + textInputProps: Object +}; /** - * Defines {@code Dialog}'s state. + * The type of the React {@code Component} state of {@link Dialog}. */ -type DialogState = { +type State = { + ...AbstractDialogState, /** * The text of the {@link TextInput} rendered by {@link Prompt} in @@ -50,18 +60,13 @@ type DialogState = { * functionality of {@code Prompt} because this {@code Dialog} does not * really render the (whole) {@code Prompt}. */ - text: String -} + text: string +}; /** * Implements {@code AbstractDialog} on react-native using {@code Prompt}. */ -class Dialog extends AbstractDialog { - - state = { - text: '' - }; - +class Dialog extends AbstractDialog { /** * Initailizes a new {@code Dialog} instance. * @@ -71,6 +76,8 @@ class Dialog extends AbstractDialog { constructor(props: Object) { super(props); + this.state.text = ''; + // Bind event handlers so they are only bound once per instance. this._onChangeText = this._onChangeText.bind(this); this._onSubmit = this._onSubmit.bind(this); @@ -89,7 +96,7 @@ class Dialog extends AbstractDialog { cancelTitleKey = 'dialog.Cancel', okDisabled, okTitleKey = 'dialog.Ok', - t, + t /* XXX The following silences flow errors: */ = _.identity, titleKey, titleString } = this.props; @@ -104,13 +111,10 @@ class Dialog extends AbstractDialog { [_TAG_KEY]: _SUBMIT_TEXT_TAG_VALUE }; - // eslint-disable-next-line no-extra-parens - let element = ( + let el: ?React$Element<*> = ( // eslint-disable-line no-extra-parens { // XXX The following implements workarounds with knowledge of // react-native-prompt/Prompt's implementation. - // eslint-disable-next-line no-extra-parens, new-cap - element = (new (element.type)(element.props)).render(); + if (el) { + // eslint-disable-next-line new-cap, no-extra-parens + el = (new (el.type)(el.props)).render(); + } let { children } = this.props; children = React.Children.count(children) ? children : undefined; // eslint-disable-next-line no-shadow - element = this._mapReactElement(element, element => { - const { type } = element; + el = this._mapReactElement(el, (el: React$Element<*>) => { + const { type } = el; if (type === Modal) { // * Modal handles hardware button presses for back navigation. @@ -144,7 +150,7 @@ 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 this._cloneElement(element, /* props */ { + return this._cloneElement(el, /* props */ { onRequestClose: this._onCancel }); } @@ -153,12 +159,13 @@ class Dialog extends AbstractDialog { // * If this Dialog has children, they are to be rendered // instead of Prompt's TextInput. if (children) { - element = children; // eslint-disable-line no-param-reassign + // $FlowFixMe + el = children; // eslint-disable-line no-param-reassign children = undefined; } } else { - let { style } = element.props; + let { style } = el.props; if (style && (style = StyleSheet.flatten(style)) @@ -177,33 +184,33 @@ class Dialog extends AbstractDialog { break; } - return this._cloneElement(element, /* props */ { + return this._cloneElement(el, /* props */ { style: set(style, _TAG_KEY, undefined) }); } } - return element; + return el; }); - return element; + return el; } /** * Clones a specific {@code ReactElement} and adds/merges specific props * into the clone. * - * @param {ReactElement} element - The {@code ReactElement} to clone. + * @param {ReactElement} el - 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 + * @returns {ReactElement} The close of the specified {@code el} with * the specified {@code props} added/merged. */ - _cloneElement(element, props) { + _cloneElement(el: React$Element<*>, props) { return ( React.cloneElement( - element, + el, props, - ...React.Children.toArray(element.props.children))); + ...React.Children.toArray(el.props.children))); } /** @@ -211,33 +218,35 @@ class Dialog extends AbstractDialog { * of calling a specific function on every node of a specific * {@code ReactElement} tree. * - * @param {ReactElement} element - The {@code ReactElement} to clone and + * @param {ReactElement} el - The {@code ReactElement} to clone and * call the specified {@code f} on. * @param {Function} f - The function to call on every node of the - * {@code ReactElement} tree represented by the specified {@code element}. + * {@code ReactElement} tree represented by the specified {@code el}. * @private * @returns {ReactElement} */ - _mapReactElement(element, f) { - if (!element || !element.props || !element.type) { - return element; + _mapReactElement( + el: ?React$Element<*>, + f: (React$Element<*>) => ?React$Element<*>): ?React$Element<*> { + if (!el || !el.props || !el.type) { + return el; } - let mapped = f(element); + let mapped = f(el); if (mapped) { const { children } = mapped.props; - if (mapped === element || React.Children.count(children)) { + if (mapped === el || React.Children.count(children)) { mapped = React.cloneElement( mapped, /* props */ {}, ...React.Children.toArray(React.Children.map( children, - function(element) { // eslint-disable-line no-shadow + function(el) { // eslint-disable-line no-shadow // eslint-disable-next-line no-invalid-this - return this._mapReactElement(element, f); + return this._mapReactElement(el, f); }, this))); } diff --git a/react/features/base/dialog/components/Dialog.web.js b/react/features/base/dialog/components/Dialog.web.js index 6807b3e4d..eec624561 100644 --- a/react/features/base/dialog/components/Dialog.web.js +++ b/react/features/base/dialog/components/Dialog.web.js @@ -1,14 +1,17 @@ +// @flow + import React from 'react'; import { connect } from 'react-redux'; -import AbstractDialog, { AbstractDialogPropTypes } from './AbstractDialog'; +import AbstractDialog from './AbstractDialog'; +import type { Props as AbstractDialogProps, State } from './AbstractDialog'; import StatelessDialog from './StatelessDialog'; /** - * Web dialog component's property types. + * The type of the React {@code Component} props of {@link Dialog}. */ -type DialogPropTypes = { - ...AbstractDialogPropTypes, +type Props = { + ...AbstractDialogProps, /** * Whether the dialog is modal. This means clicking on the blanket will @@ -28,13 +31,13 @@ type DialogPropTypes = { * - integer value for pixel width * - string value for percentage */ - width: String -} + width: string +}; /** * Web dialog that uses atlaskit modal-dialog to display dialogs. */ -class Dialog extends AbstractDialog { +class Dialog extends AbstractDialog { /** * Initializes a new Dialog instance. * @@ -44,6 +47,7 @@ class Dialog extends AbstractDialog { constructor(props) { super(props); + // Bind event handlers so they are only bound once per instance. this._onCancel = this._onCancel.bind(this); this._onSubmit = this._onSubmit.bind(this); } @@ -66,6 +70,8 @@ class Dialog extends AbstractDialog { return ; } + _onCancel: () => void; + /** * Dispatches action to hide the dialog. * @@ -74,6 +80,8 @@ class Dialog extends AbstractDialog { _onCancel() { this.props.isModal || super._onCancel(); } + + _onSubmit: (?string) => void; } export default connect()(Dialog); diff --git a/react/features/base/dialog/components/StatelessDialog.web.js b/react/features/base/dialog/components/StatelessDialog.web.js index 52ce022c8..161df3744 100644 --- a/react/features/base/dialog/components/StatelessDialog.web.js +++ b/react/features/base/dialog/components/StatelessDialog.web.js @@ -1,12 +1,14 @@ +// @flow + import Button, { ButtonGroup } from '@atlaskit/button'; import ModalDialog from '@atlaskit/modal-dialog'; import { AtlasKitThemeProvider } from '@atlaskit/theme'; -import PropTypes from 'prop-types'; +import _ from 'lodash'; import React, { Component } from 'react'; import { translate } from '../../i18n'; -import { DIALOG_PROP_TYPES } from '../constants'; +import type { DialogProps } from '../constants'; /** * The ID to be used for the cancel button if enabled. @@ -20,49 +22,46 @@ const CANCEL_BUTTON_ID = 'modal-dialog-cancel-button'; */ const OK_BUTTON_ID = 'modal-dialog-ok-button'; +/** + * The type of the React {@code Component} props of {@link StatelessDialog}. + * + * @static + */ +type Props = { + ...DialogProps, + + /** + * Disables dismissing the dialog when the blanket is clicked. Enabled + * by default. + */ + disableBlanketClickDismiss: boolean, + + /** + * Whether the dialog is modal. This means clicking on the blanket will + * leave the dialog open. No cancel button. + */ + isModal: boolean, + + /** + * Disables rendering of the submit button. + */ + submitDisabled: boolean, + + /** + * Width of the dialog, can be: + * - 'small' (400px), 'medium' (600px), 'large' (800px), + * 'x-large' (968px) + * - integer value for pixel width + * - string value for percentage + */ + width: string +}; + /** * Web dialog that uses atlaskit modal-dialog to display dialogs. */ -class StatelessDialog extends Component { - /** - * {@code StatelessDialog} component's property types. - * - * @static - */ - static propTypes = { - ...DIALOG_PROP_TYPES, - - /** - * This is the body of the dialog, the component children. - */ - children: PropTypes.node, - - /** - * Disables dismissing the dialog when the blanket is clicked. Enabled - * by default. - */ - disableBlanketClickDismiss: PropTypes.bool, - - /** - * Whether the dialog is modal. This means clicking on the blanket will - * leave the dialog open. No cancel button. - */ - isModal: PropTypes.bool, - - /** - * Disables rendering of the submit button. - */ - submitDisabled: PropTypes.bool, - - /** - * Width of the dialog, can be: - * - 'small' (400px), 'medium' (600px), 'large' (800px), - * 'x-large' (968px) - * - integer value for pixel width - * - string value for percentage - */ - width: PropTypes.string - }; +class StatelessDialog extends Component { + _dialogElement: ?HTMLElement; /** * Initializes a new {@code StatelessDialog} instance. @@ -100,8 +99,8 @@ class StatelessDialog extends Component { // if there is an update in any of the buttons enable/disable props // update the focus if needed if (prevProps.okDisabled !== this.props.okDisabled - || prevProps.cancelDisabled !== this.props.cancelDisabled - || prevProps.submitDisabled !== this.props.submitDisabled) { + || prevProps.cancelDisabled !== this.props.cancelDisabled + || prevProps.submitDisabled !== this.props.submitDisabled) { this._updateButtonFocus(); } } @@ -143,6 +142,8 @@ class StatelessDialog extends Component { ); } + _onCancel: () => void; + /** * Dispatches action to hide the dialog. * @@ -150,10 +151,14 @@ class StatelessDialog extends Component { */ _onCancel() { if (!this.props.isModal) { - this.props.onCancel(); + const { onCancel } = this.props; + + onCancel && onCancel(); } } + _onDialogDismissed: () => void; + /** * Handles click on the blanket area. * @@ -165,6 +170,8 @@ class StatelessDialog extends Component { } } + _onSubmit: (?string) => void; + /** * Dispatches the action when submitting the dialog. * @@ -173,7 +180,9 @@ class StatelessDialog extends Component { * @returns {void} */ _onSubmit(value) { - this.props.onSubmit(value); + const { onSubmit } = this.props; + + onSubmit && onSubmit(value); } /** @@ -187,6 +196,10 @@ class StatelessDialog extends Component { return null; } + const { + t /* The following fixes a flow error: */ = _.identity + } = this.props; + return ( ); } @@ -229,7 +242,9 @@ class StatelessDialog extends Component { * @returns {ReactElement} */ _renderHeader() { - const { t } = this.props; + const { + t /* The following fixes a flow error: */ = _.identity + } = this.props; return (

@@ -251,6 +266,10 @@ class StatelessDialog extends Component { return null; } + const { + t /* The following fixes a flow error: */ = _.identity + } = this.props; + return ( ); } + _setDialogElement: (?HTMLElement) => void; + /** * Sets the instance variable for the div containing the component's dialog * element so it can be accessed directly. * - * @param {Object} element - The DOM element for the component's dialog. + * @param {HTMLElement} element - The DOM element for the component's + * dialog. * @private * @returns {void} */ - _setDialogElement(element) { + _setDialogElement(element: ?HTMLElement) { this._dialogElement = element; } + _onKeyDown: (Object) => void; + /** * Handles 'Enter' key in the dialog to submit/hide dialog depending on * the available buttons and their disabled state. @@ -312,22 +336,24 @@ class StatelessDialog extends Component { * @returns {void} */ _updateButtonFocus() { - if (this._dialogElement) { + const dialogElement = this._dialogElement; + + if (dialogElement) { // if we have a focused element inside the dialog, skip changing // the focus - if (this._dialogElement.contains(document.activeElement)) { + if (dialogElement.contains(document.activeElement)) { return; } let buttonToFocus; if (this.props.submitDisabled) { - buttonToFocus = this._dialogElement - .querySelector(`[id=${CANCEL_BUTTON_ID}]`); + buttonToFocus + = dialogElement.querySelector(`[id=${CANCEL_BUTTON_ID}]`); } else if (!this.props.okDisabled) { - buttonToFocus = this._dialogElement - .querySelector(`[id=${OK_BUTTON_ID}]`); + buttonToFocus + = dialogElement.querySelector(`[id=${OK_BUTTON_ID}]`); } if (buttonToFocus) { diff --git a/react/features/base/dialog/constants.js b/react/features/base/dialog/constants.js index dcc8b3c41..a86d034b5 100644 --- a/react/features/base/dialog/constants.js +++ b/react/features/base/dialog/constants.js @@ -1,5 +1,6 @@ +// @flow -export type DialogPropTypes = { +export type DialogProps = { /** * Whether cancel button is disabled. Enabled by default. @@ -9,7 +10,12 @@ export type DialogPropTypes = { /** * Optional i18n key to change the cancel button title. */ - cancelTitleKey: String, + cancelTitleKey: string, + + /** + * The React {@code Component} children which represents the dialog's body. + */ + children: React$Node, /** * Is ok button enabled/disabled. Enabled by default. @@ -19,7 +25,7 @@ export type DialogPropTypes = { /** * Optional i18n key to change the ok button title. */ - okTitleKey: String, + okTitleKey: string, /** * The handler for onCancel event. @@ -39,12 +45,12 @@ export type DialogPropTypes = { /** * Key to use for showing a title. */ - titleKey: String, + titleKey: string, /** * The string to use as a title instead of {@code titleKey}. If a truthy * value is specified, it takes precedence over {@code titleKey} i.e. * the latter is unused. */ - titleString: String + titleString: string }; diff --git a/react/features/conference/components/Conference.native.js b/react/features/conference/components/Conference.native.js index 5f635a3aa..2e1ec6290 100644 --- a/react/features/conference/components/Conference.native.js +++ b/react/features/conference/components/Conference.native.js @@ -1,3 +1,5 @@ +// @flow + import React, { Component } from 'react'; // eslint-disable-next-line react-native/split-platform-components @@ -25,11 +27,9 @@ import styles from './styles'; const _TOOLBOX_TIMEOUT_MS = 5000; /** - * Conference component's property types. - * - * @static + * The type of the React {@code Component} props of {@link Conference}. */ -type ConferencePropTypes = { +type Props = { /** * The indicator which determines that we are still connecting to the @@ -85,7 +85,11 @@ type ConferencePropTypes = { /** * The conference page of the mobile (i.e. React Native) application. */ -class Conference extends Component { +class Conference extends Component { + _backHandler: ?BackHandler; + + _toolboxTimeout: ?number; + /** * Initializes a new Conference instance. * @@ -237,6 +241,8 @@ class Conference extends Component { } } + _onClick: () => void; + /** * Changes the value of the toolboxVisible state, thus allowing us to switch * between Toolbox and Filmstrip and change their visibility. @@ -254,6 +260,8 @@ class Conference extends Component { this._clearToolboxTimeout(); } + _onHardwareBackPress: () => boolean; + /** * Handles a hardware button press for back navigation. * @@ -393,5 +401,6 @@ function _mapStateToProps(state) { }; } +// $FlowFixMe export default reactReduxConnect(_mapStateToProps, _mapDispatchToProps)( Conference); diff --git a/react/features/feedback/components/FeedbackButton.web.js b/react/features/feedback/components/FeedbackButton.web.js index f6a3a7969..75cd67a39 100644 --- a/react/features/feedback/components/FeedbackButton.web.js +++ b/react/features/feedback/components/FeedbackButton.web.js @@ -1,4 +1,4 @@ -/* @flow */ +// @flow import Tooltip from '@atlaskit/tooltip'; import React, { Component } from 'react'; @@ -9,9 +9,9 @@ import { translate } from '../../base/i18n'; import { openFeedbackDialog } from '../actions'; /** - * Defines property types for the FeedbackButton component. + * The type of the React {@code Component} props of {@link FeedbackButton}. */ -type FeedbackButtonPropTypes = { +type Props = { /** * The JitsiConference for which the feedback will be about. @@ -34,13 +34,13 @@ type FeedbackButtonPropTypes = { /** * From which side of the button the tooltip should appear from. */ - tooltipPosition: String + tooltipPosition: string } /** * Implements a Web/React Component which renders a feedback button. */ -class FeedbackButton extends Component { +class FeedbackButton extends Component { _onClick: Function; /**