From 4ac367d40353e694576dc08ecf19ef7d37362e10 Mon Sep 17 00:00:00 2001 From: Bettenbuk Zoltan Date: Thu, 14 Jun 2018 13:14:17 +0200 Subject: [PATCH] [RN] Implement Labels on mobile --- .../components/Conference.native.js | 8 -- .../components/ConferenceIndicators.native.js | 81 ------------------- .../components/ConferenceIndicators.web.js | 0 .../features/conference/components/styles.js | 19 ----- .../large-video/components/AbstractLabels.js | 69 ++++++++++++++++ .../large-video/components/Labels.native.js | 81 +++++++++++++++++++ .../large-video/components/Labels.web.js | 81 +++++-------------- .../components/LargeVideo.native.js | 2 + .../features/large-video/components/styles.js | 26 +++++- 9 files changed, 198 insertions(+), 169 deletions(-) delete mode 100644 react/features/conference/components/ConferenceIndicators.native.js delete mode 100644 react/features/conference/components/ConferenceIndicators.web.js create mode 100644 react/features/large-video/components/AbstractLabels.js diff --git a/react/features/conference/components/Conference.native.js b/react/features/conference/components/Conference.native.js index 58ac30e35..e25f8c6c3 100644 --- a/react/features/conference/components/Conference.native.js +++ b/react/features/conference/components/Conference.native.js @@ -20,7 +20,6 @@ import { LargeVideo } from '../../large-video'; import { NotificationsContainer } from '../../notifications'; import { setToolboxVisible, Toolbox } from '../../toolbox'; -import ConferenceIndicators from './ConferenceIndicators'; import styles from './styles'; /** @@ -254,13 +253,6 @@ class Conference extends Component { * participants. */} - - {/* - * Examples of conference indicators are VideoQualityLabel - * and RecordingLabel. - */ - this.props._reducedUI || - } diff --git a/react/features/conference/components/ConferenceIndicators.native.js b/react/features/conference/components/ConferenceIndicators.native.js deleted file mode 100644 index 67a82e5e4..000000000 --- a/react/features/conference/components/ConferenceIndicators.native.js +++ /dev/null @@ -1,81 +0,0 @@ -// @flow -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { connect } from 'react-redux'; - -import { JitsiRecordingConstants } from '../../base/lib-jitsi-meet'; -import { - isNarrowAspectRatio, - makeAspectRatioAware -} from '../../base/responsive-ui'; -import { RecordingLabel } from '../../recording'; -import { VideoQualityLabel } from '../../video-quality'; - -import styles from './styles'; - -type Props = { - - /** - * The indicator which determines whether the filmstrip is visible. - */ - _filmstripVisible: boolean -}; - -/** - * A container that renders the conference indicators, if any. - */ -class ConferenceIndicators extends Component { - /** - * Implements React {@code Component}'s render. - * - * @inheritdoc - */ - render() { - const _wide = !isNarrowAspectRatio(this); - const { _filmstripVisible } = this.props; - - return ( - - - - - - ); - } - -} - -/** - * Maps (parts of) the redux state to the associated - * {@code ConferenceIndicators}'s props. - * - * @param {Object} state - The redux state. - * @private - * @returns {{ - * _filmstripVisible: boolean - * }} - */ -function _mapStateToProps(state) { - const { length: participantCount } = state['features/base/participants']; - const { visible } = state['features/filmstrip']; - - return { - /** - * The indicator which determines whether the filmstrip is visible. - * - * @private - * @type {boolean} - */ - _filmstripVisible: visible && participantCount > 1 - }; -} - -export default connect(_mapStateToProps)( - makeAspectRatioAware(ConferenceIndicators) -); diff --git a/react/features/conference/components/ConferenceIndicators.web.js b/react/features/conference/components/ConferenceIndicators.web.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/react/features/conference/components/styles.js b/react/features/conference/components/styles.js index 51b7368fb..774044a5d 100644 --- a/react/features/conference/components/styles.js +++ b/react/features/conference/components/styles.js @@ -18,25 +18,6 @@ export default createStyleSheet({ flex: 1 }), - /** - * View that contains the indicators. - */ - indicatorContainer: { - flex: 1, - flexDirection: 'row', - margin: BoxModel.margin, - position: 'absolute', - right: 0, - top: 0 - }, - - /** - * Indicator container for wide aspect ratio. - */ - indicatorContainerWide: { - right: 80 - }, - /** * The style of the {@link View} which expands over the whole * {@link Conference} area and splits it between the {@link Filmstrip} and diff --git a/react/features/large-video/components/AbstractLabels.js b/react/features/large-video/components/AbstractLabels.js new file mode 100644 index 000000000..206d7bb3f --- /dev/null +++ b/react/features/large-video/components/AbstractLabels.js @@ -0,0 +1,69 @@ +// @flow + +import React, { Component } from 'react'; + +import { isFilmstripVisible } from '../../filmstrip'; +import { RecordingLabel } from '../../recording'; +import { VideoQualityLabel } from '../../video-quality'; + +/** + * The type of the React {@code Component} props of {@link AbstractLabels}. + */ +export type Props = { + + /** + * Whether or not the filmstrip is displayed with remote videos. Used to + * determine display classes to set. + */ + _filmstripVisible: boolean, +}; + +/** + * A container to hold video status labels, including recording status and + * current large video quality. + * + * @extends Component + */ +export default class AbstractLabels extends Component { + /** + * Renders the {@code RecordingLabel} that is platform independent. + * + * @protected + * @param {string} mode - The recording mode that this label is rendered + * for. + * @returns {React$Element} + */ + _renderRecordingLabel(mode: string) { + return ( + + ); + } + + /** + * Renders the {@code VideoQualityLabel} that is platform independent. + * + * @protected + * @returns {React$Element} + */ + _renderVideoQualityLabel() { + return ( + + ); + } +} + +/** + * Maps (parts of) the Redux state to the associated props for the + * {@code Labels} component. + * + * @param {Object} state - The Redux state. + * @private + * @returns {{ + * _filmstripVisible: boolean + * }} + */ +export function _abstractMapStateToProps(state: Object) { + return { + _filmstripVisible: isFilmstripVisible(state) + }; +} diff --git a/react/features/large-video/components/Labels.native.js b/react/features/large-video/components/Labels.native.js index e69de29bb..99749eaea 100644 --- a/react/features/large-video/components/Labels.native.js +++ b/react/features/large-video/components/Labels.native.js @@ -0,0 +1,81 @@ +// @flow +import React from 'react'; +import { View } from 'react-native'; +import { connect } from 'react-redux'; + +import { JitsiRecordingConstants } from '../../base/lib-jitsi-meet'; +import { + isNarrowAspectRatio, + makeAspectRatioAware +} from '../../base/responsive-ui'; +import { isFilmstripVisible } from '../../filmstrip'; + +import AbstractLabels, { type Props } from './AbstractLabels'; +import styles from './styles'; + +/** + * A container that renders the conference indicators, if any. + */ +class Labels extends AbstractLabels { + /** + * Implements React {@code Component}'s render. + * + * @inheritdoc + */ + render() { + const _wide = !isNarrowAspectRatio(this); + const { _filmstripVisible } = this.props; + + return ( + + { + this._renderRecordingLabel( + JitsiRecordingConstants.mode.FILE) + } + { + this._renderRecordingLabel( + JitsiRecordingConstants.mode.STREAM) + } + { + this._renderVideoQualityLabel() + } + + ); + } + + _renderRecordingLabel: string => React$Element<*> + + _renderVideoQualityLabel: () => React$Element<*> + +} + +/** + * Maps (parts of) the redux state to the associated + * {@code Labels}'s props. + * + * @param {Object} state - The redux state. + * @private + * @returns {{ + * _filmstripVisible: boolean + * }} + */ +function _mapStateToProps(state) { + return { + /** + * The indicator which determines whether the filmstrip is visible. + * + * @private + * @type {boolean} + */ + _filmstripVisible: isFilmstripVisible(state) + }; +} + +export default connect(_mapStateToProps)( + makeAspectRatioAware(Labels) +); diff --git a/react/features/large-video/components/Labels.web.js b/react/features/large-video/components/Labels.web.js index 90ecdd811..6649c3767 100644 --- a/react/features/large-video/components/Labels.web.js +++ b/react/features/large-video/components/Labels.web.js @@ -1,28 +1,14 @@ // @flow -import React, { Component } from 'react'; +import React from 'react'; import { connect } from 'react-redux'; -import { RecordingLabel } from '../../recording'; -import { VideoQualityLabel } from '../../video-quality'; +import { JitsiRecordingConstants } from '../../base/lib-jitsi-meet'; -/** - * The type of the React {@code Component} props of {@link Labels}. - */ -type Props = { - - /** - * Whether or not the filmstrip is displayed with remote videos. Used to - * determine display classes to set. - */ - _filmstripVisible: boolean, - - - /** - * The redux state for all known recording sessions. - */ - _recordingSessions: Array -}; +import AbstractLabels, { + _abstractMapStateToProps as _mapStateToProps, + type Props +} from './AbstractLabels'; /** * The type of the React {@code Component} state of {@link Labels}. @@ -45,7 +31,7 @@ type State = { * * @extends Component */ -class Labels extends Component { +class Labels extends AbstractLabels { /** * Initializes a new {@code Labels} instance. * @@ -58,9 +44,6 @@ class Labels extends Component { this.state = { filmstripBecomingVisible: false }; - - // Bind event handler so it is only bound once for every instance. - this._renderRecordingLabel = this._renderRecordingLabel.bind(this); } /** @@ -86,7 +69,7 @@ class Labels extends Component { * @returns {ReactElement} */ render() { - const { _filmstripVisible, _recordingSessions } = this.props; + const { _filmstripVisible } = this.props; const { filmstripBecomingVisible } = this.state; const className = `large-video-labels ${ filmstripBecomingVisible ? 'opening' : ''} ${ @@ -94,46 +77,24 @@ class Labels extends Component { return (
- { _recordingSessions.map(this._renderRecordingLabel) } - + { + this._renderRecordingLabel( + JitsiRecordingConstants.mode.FILE) + } + { + this._renderRecordingLabel( + JitsiRecordingConstants.mode.STREAM) + } + { + this._renderVideoQualityLabel() + }
); } - _renderRecordingLabel: (Object) => React$Node; + _renderRecordingLabel: string => React$Element<*> - /** - * Renders a recording label. - * - * @param {Object} recordingSession - The recording session to render. - * @private - * @returns {ReactElement} - */ - _renderRecordingLabel(recordingSession) { - return ( - - ); - } -} - -/** - * Maps (parts of) the Redux state to the associated props for the - * {@code Labels} component. - * - * @param {Object} state - The Redux state. - * @private - * @returns {{ - * _filmstripVisible: boolean, - * _recordingSessions: Array - * }} - */ -function _mapStateToProps(state) { - return { - _filmstripVisible: state['features/filmstrip'].visible, - _recordingSessions: state['features/recording'].sessionDatas - }; + _renderVideoQualityLabel: () => React$Element<*> } export default connect(_mapStateToProps)(Labels); diff --git a/react/features/large-video/components/LargeVideo.native.js b/react/features/large-video/components/LargeVideo.native.js index f0bd5dd2a..66a2ee6c9 100644 --- a/react/features/large-video/components/LargeVideo.native.js +++ b/react/features/large-video/components/LargeVideo.native.js @@ -6,6 +6,7 @@ import { connect } from 'react-redux'; import { ParticipantView } from '../../base/participants'; import { DimensionsDetector } from '../../base/responsive-ui'; +import Labels from './Labels'; import styles, { AVATAR_SIZE } from './styles'; /** @@ -129,6 +130,7 @@ class LargeVideo extends Component { useConnectivityInfoLabel = { useConnectivityInfoLabel } zOrder = { 0 } zoomEnabled = { true } /> + ); } diff --git a/react/features/large-video/components/styles.js b/react/features/large-video/components/styles.js index 422a41307..b4f61d44d 100644 --- a/react/features/large-video/components/styles.js +++ b/react/features/large-video/components/styles.js @@ -1,6 +1,7 @@ import { StyleSheet } from 'react-native'; -import { ColorPalette, createStyleSheet } from '../../base/styles'; +import { BoxModel, ColorPalette, createStyleSheet } from '../../base/styles'; +import { FILMSTRIP_SIZE } from '../../filmstrip'; /** * Size for the Avatar. @@ -8,6 +9,29 @@ import { ColorPalette, createStyleSheet } from '../../base/styles'; export const AVATAR_SIZE = 200; export default createStyleSheet({ + /** + * View that contains the indicators. + */ + indicatorContainer: { + flex: 1, + flexDirection: 'row', + margin: BoxModel.margin, + position: 'absolute', + right: 0, + + // Both on Android and iOS there is the status bar which may be visible. + // On iPhone X there is the notch. In the two cases BoxModel.margin is + // not enough. + top: BoxModel.margin * 3 + }, + + /** + * Indicator container for wide aspect ratio. + */ + indicatorContainerWide: { + right: FILMSTRIP_SIZE + }, + /** * Large video container style. */