[RN] Implement Labels on mobile
This commit is contained in:
parent
ffd0827354
commit
4ac367d403
|
@ -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<Props> {
|
|||
* participants.
|
||||
*/}
|
||||
<Filmstrip />
|
||||
|
||||
{/*
|
||||
* Examples of conference indicators are VideoQualityLabel
|
||||
* and RecordingLabel.
|
||||
*/
|
||||
this.props._reducedUI || <ConferenceIndicators />
|
||||
}
|
||||
</View>
|
||||
<TestConnectionInfo />
|
||||
|
||||
|
|
|
@ -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<Props> {
|
||||
/**
|
||||
* Implements React {@code Component}'s render.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const _wide = !isNarrowAspectRatio(this);
|
||||
const { _filmstripVisible } = this.props;
|
||||
|
||||
return (
|
||||
<View
|
||||
style = { [
|
||||
styles.indicatorContainer,
|
||||
_wide && _filmstripVisible && styles.indicatorContainerWide
|
||||
] }>
|
||||
<RecordingLabel
|
||||
mode = { JitsiRecordingConstants.mode.FILE } />
|
||||
<RecordingLabel
|
||||
mode = { JitsiRecordingConstants.mode.STREAM } />
|
||||
<VideoQualityLabel />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
);
|
|
@ -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
|
||||
|
|
|
@ -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<P: Props, S> extends Component<P, S> {
|
||||
/**
|
||||
* 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 (
|
||||
<RecordingLabel mode = { mode } />
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the {@code VideoQualityLabel} that is platform independent.
|
||||
*
|
||||
* @protected
|
||||
* @returns {React$Element}
|
||||
*/
|
||||
_renderVideoQualityLabel() {
|
||||
return (
|
||||
<VideoQualityLabel />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
};
|
||||
}
|
|
@ -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<Props, *> {
|
||||
/**
|
||||
* Implements React {@code Component}'s render.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const _wide = !isNarrowAspectRatio(this);
|
||||
const { _filmstripVisible } = this.props;
|
||||
|
||||
return (
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { [
|
||||
styles.indicatorContainer,
|
||||
_wide && _filmstripVisible && styles.indicatorContainerWide
|
||||
] }>
|
||||
{
|
||||
this._renderRecordingLabel(
|
||||
JitsiRecordingConstants.mode.FILE)
|
||||
}
|
||||
{
|
||||
this._renderRecordingLabel(
|
||||
JitsiRecordingConstants.mode.STREAM)
|
||||
}
|
||||
{
|
||||
this._renderVideoQualityLabel()
|
||||
}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_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)
|
||||
);
|
|
@ -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<Object>
|
||||
};
|
||||
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<Props, State> {
|
||||
class Labels extends AbstractLabels<Props, State> {
|
||||
/**
|
||||
* Initializes a new {@code Labels} instance.
|
||||
*
|
||||
|
@ -58,9 +44,6 @@ class Labels extends Component<Props, State> {
|
|||
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<Props, State> {
|
|||
* @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<Props, State> {
|
|||
|
||||
return (
|
||||
<div className = { className } >
|
||||
{ _recordingSessions.map(this._renderRecordingLabel) }
|
||||
<VideoQualityLabel />
|
||||
{
|
||||
this._renderRecordingLabel(
|
||||
JitsiRecordingConstants.mode.FILE)
|
||||
}
|
||||
{
|
||||
this._renderRecordingLabel(
|
||||
JitsiRecordingConstants.mode.STREAM)
|
||||
}
|
||||
{
|
||||
this._renderVideoQualityLabel()
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_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 (
|
||||
<RecordingLabel
|
||||
key = { recordingSession.id }
|
||||
session = { recordingSession } />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<Object>
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_filmstripVisible: state['features/filmstrip'].visible,
|
||||
_recordingSessions: state['features/recording'].sessionDatas
|
||||
};
|
||||
_renderVideoQualityLabel: () => React$Element<*>
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps)(Labels);
|
||||
|
|
|
@ -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<Props, State> {
|
|||
useConnectivityInfoLabel = { useConnectivityInfoLabel }
|
||||
zOrder = { 0 }
|
||||
zoomEnabled = { true } />
|
||||
<Labels />
|
||||
</DimensionsDetector>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue