[RN] Dynamically adjust LargeView's Avatar to available size (Coding style: comments, flow)
Flow caught an incorrect function call.
This commit is contained in:
parent
1419247801
commit
cacc4bd769
|
@ -42,7 +42,7 @@ type Props = {
|
|||
/**
|
||||
* I18n key to put as body title.
|
||||
*/
|
||||
bodyKey: String,
|
||||
bodyKey: string,
|
||||
|
||||
textInputProps: Object
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import PropTypes from 'prop-types';
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { Image, View } from 'react-native';
|
||||
|
||||
|
@ -23,36 +24,48 @@ import styles from './styles';
|
|||
*/
|
||||
const _DEFAULT_SOURCE = require('../../../../../images/avatar.png');
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} props of {@link Avatar}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The size for the {@link Avatar}.
|
||||
*/
|
||||
size: number,
|
||||
|
||||
|
||||
/**
|
||||
* The URI of the {@link Avatar}.
|
||||
*/
|
||||
uri: string
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} state of {@link Avatar}.
|
||||
*/
|
||||
type State = {
|
||||
backgroundColor: string,
|
||||
source: number | { uri: string }
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements an avatar as a React Native/mobile {@link Component}.
|
||||
*/
|
||||
export default class Avatar extends Component {
|
||||
export default class Avatar extends Component<Props, State> {
|
||||
/**
|
||||
* Avatar component's property types.
|
||||
*
|
||||
* @static
|
||||
* The indicator which determines whether this {@code Avatar} has been
|
||||
* unmounted.
|
||||
*/
|
||||
static propTypes = {
|
||||
/**
|
||||
* The size for the {@link Avatar}.
|
||||
*/
|
||||
size: PropTypes.number,
|
||||
|
||||
/**
|
||||
* The URI of the {@link Avatar}.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
uri: PropTypes.string
|
||||
};
|
||||
_unmounted: ?boolean;
|
||||
|
||||
/**
|
||||
* Initializes a new Avatar instance.
|
||||
*
|
||||
* @param {Object} props - The read-only React Component props with which
|
||||
* @param {Props} props - The read-only React Component props with which
|
||||
* the new instance is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
// Fork (in Facebook/React speak) the prop uri because Image will
|
||||
|
@ -68,11 +81,11 @@ export default class Avatar extends Component {
|
|||
* Additionally, other props may be forked as well.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @param {Object} nextProps - The read-only React Component props that this
|
||||
* @param {Props} nextProps - The read-only React Component props that this
|
||||
* instance will receive.
|
||||
* @returns {void}
|
||||
*/
|
||||
componentWillReceiveProps(nextProps) {
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
// uri
|
||||
const prevURI = this.props && this.props.uri;
|
||||
const nextURI = nextProps && nextProps.uri;
|
||||
|
@ -226,14 +239,17 @@ export default class Avatar extends Component {
|
|||
} = this.state;
|
||||
|
||||
// Compute the base style
|
||||
const borderRadius = size / 2;
|
||||
const style = {
|
||||
...styles.avatar,
|
||||
|
||||
// XXX Workaround for Android: for radii < 80 the border radius
|
||||
// doesn't work properly, but applying a radius twice as big
|
||||
// seems to do the trick.
|
||||
borderRadius: size / 2 < 80
|
||||
? Platform.OS === 'android' ? size * 2 : size / 2 : size / 2,
|
||||
// doesn't work properly, but applying a radius twice as big seems
|
||||
// to do the trick.
|
||||
borderRadius:
|
||||
Platform.OS === 'android' && borderRadius < 80
|
||||
? size * 2
|
||||
: borderRadius,
|
||||
height: size,
|
||||
width: size
|
||||
};
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
import PropTypes from 'prop-types';
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} props of {@link Avatar}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The URI of the {@link Avatar}.
|
||||
*/
|
||||
uri: string
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements an avatar as a React/Web {@link Component}.
|
||||
*/
|
||||
export default class Avatar extends Component {
|
||||
/**
|
||||
* Avatar component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
/**
|
||||
* The URI of the {@link Avatar}.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
uri: PropTypes.string
|
||||
};
|
||||
|
||||
export default class Avatar extends Component<Props> {
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import PropTypes from 'prop-types';
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { prefetch } from '../../../mobile/image-cache';
|
||||
|
||||
import { translate } from '../../i18n';
|
||||
import { JitsiParticipantConnectionStatus } from '../../lib-jitsi-meet';
|
||||
import {
|
||||
|
@ -12,116 +11,117 @@ import {
|
|||
shouldRenderVideoTrack,
|
||||
VideoTrack
|
||||
} from '../../media';
|
||||
import { prefetch } from '../../../mobile/image-cache';
|
||||
import { Container, TintedView } from '../../react';
|
||||
import { getTrackByMediaTypeAndParticipant } from '../../tracks';
|
||||
|
||||
import {
|
||||
getAvatarURL, getParticipantById, getParticipantDisplayName
|
||||
} from '../functions';
|
||||
|
||||
import Avatar from './Avatar';
|
||||
import {
|
||||
getAvatarURL,
|
||||
getParticipantById,
|
||||
getParticipantDisplayName
|
||||
} from '../functions';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} props of {@link ParticipantView}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The indicator which determines whether conferencing is in audio-only
|
||||
* mode.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_audioOnly: boolean,
|
||||
|
||||
/**
|
||||
* The source (e.g. URI, URL) of the avatar image of the participant with
|
||||
* {@link #participantId}.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_avatar: string,
|
||||
|
||||
/**
|
||||
* The connection status of the participant. Her video will only be rendered
|
||||
* if the connection status is 'active'; otherwise, the avatar will be
|
||||
* rendered. If undefined, 'active' is presumed.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_connectionStatus: string,
|
||||
|
||||
/**
|
||||
* The name of the participant which this component represents.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_participantName: string,
|
||||
|
||||
/**
|
||||
* The video Track of the participant with {@link #participantId}.
|
||||
*/
|
||||
_videoTrack: Object,
|
||||
|
||||
/**
|
||||
* The avatar size.
|
||||
*/
|
||||
avatarSize: number,
|
||||
|
||||
/**
|
||||
* The ID of the participant (to be) depicted by {@link ParticipantView}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
participantId: string,
|
||||
|
||||
/**
|
||||
* True if the avatar of the depicted participant is to be shown should the
|
||||
* avatar be available and the video of the participant is not to be shown;
|
||||
* otherwise, false. If undefined, defaults to true.
|
||||
*/
|
||||
showAvatar: boolean,
|
||||
|
||||
/**
|
||||
* True if the video of the depicted participant is to be shown should the
|
||||
* video be available. If undefined, defaults to true.
|
||||
*/
|
||||
showVideo: boolean,
|
||||
|
||||
/**
|
||||
* The style, if any, to apply to {@link ParticipantView} in addition to its
|
||||
* default style.
|
||||
*/
|
||||
style: Object,
|
||||
|
||||
/**
|
||||
* The function to translate human-readable text.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Indicates if the connectivity info label should be shown, if appropriate.
|
||||
* It will be shown in case the connection is interrupted.
|
||||
*/
|
||||
useConnectivityInfoLabel: boolean,
|
||||
|
||||
/**
|
||||
* The z-order of the {@link Video} of {@link ParticipantView} in the
|
||||
* stacking space of all {@code Video}s. For more details, refer to the
|
||||
* {@code zOrder} property of the {@code Video} class for React Native.
|
||||
*/
|
||||
zOrder: number
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements a React Component which depicts a specific participant's avatar
|
||||
* and video.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
class ParticipantView extends Component {
|
||||
/**
|
||||
* ParticipantView component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
/**
|
||||
* The indicator which determines whether conferencing is in audio-only
|
||||
* mode.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_audioOnly: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* The source (e.g. URI, URL) of the avatar image of the participant
|
||||
* with {@link #participantId}.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_avatar: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The connection status of the participant. Her video will only be
|
||||
* rendered if the connection status is 'active'; otherwise, the avatar
|
||||
* will be rendered. If undefined, 'active' is presumed.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_connectionStatus: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The name of the participant which this component represents.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_participantName: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The video Track of the participant with {@link #participantId}.
|
||||
*/
|
||||
_videoTrack: PropTypes.object,
|
||||
|
||||
/**
|
||||
* The avatar size.
|
||||
*/
|
||||
avatarSize: PropTypes.number,
|
||||
|
||||
/**
|
||||
* The ID of the participant (to be) depicted by ParticipantView.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
participantId: PropTypes.string,
|
||||
|
||||
/**
|
||||
* True if the avatar of the depicted participant is to be shown should
|
||||
* the avatar be available and the video of the participant is not to be
|
||||
* shown; otherwise, false. If undefined, defaults to true.
|
||||
*/
|
||||
showAvatar: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* True if the video of the depicted participant is to be shown should
|
||||
* the video be available. If undefined, defaults to true.
|
||||
*/
|
||||
showVideo: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* The style, if any, to apply to ParticipantView in addition to its
|
||||
* default style.
|
||||
*/
|
||||
style: PropTypes.object,
|
||||
|
||||
/**
|
||||
* The function to translate human-readable text.
|
||||
*/
|
||||
t: PropTypes.func,
|
||||
|
||||
/**
|
||||
* Indicates if the connectivity info label should be shown, if
|
||||
* appropriate. It will be shown in case the connection is interrupted.
|
||||
*/
|
||||
useConnectivityInfoLabel: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* The z-order of the Video of ParticipantView in the stacking space of
|
||||
* all Videos. For more details, refer to the zOrder property of the
|
||||
* Video class for React Native.
|
||||
*/
|
||||
zOrder: PropTypes.number
|
||||
};
|
||||
|
||||
class ParticipantView extends Component<Props> {
|
||||
/**
|
||||
* Renders the connection status label, if appropriate.
|
||||
*
|
||||
|
@ -150,8 +150,8 @@ class ParticipantView extends Component {
|
|||
t
|
||||
} = this.props;
|
||||
|
||||
// XXX Consider splitting this component into 2: one for the large
|
||||
// view and one for the thumbnail. Some of these don't apply to both.
|
||||
// XXX Consider splitting this component into 2: one for the large view
|
||||
// and one for the thumbnail. Some of these don't apply to both.
|
||||
const containerStyle = {
|
||||
...styles.connectionInfoContainer,
|
||||
width: avatarSize * 1.5
|
||||
|
@ -261,16 +261,18 @@ function _toBoolean(value, undefinedValue) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Maps (parts of) the Redux state to the associated ParticipantView's props.
|
||||
* Maps (parts of) the redux state to the associated {@link ParticipantView}'s
|
||||
* props.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @param {Object} ownProps - The React Component props passed to the associated
|
||||
* (instance of) ParticipantView.
|
||||
* @param {Object} state - The redux state.
|
||||
* @param {Object} ownProps - The React {@code Component} props passed to the
|
||||
* associated (instance of) {@code ParticipantView}.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _audioOnly: boolean,
|
||||
* _avatar: string,
|
||||
* _connectionStatus: string,
|
||||
* _participantName: string,
|
||||
* _videoTrack: Track
|
||||
* }}
|
||||
*/
|
||||
|
@ -287,7 +289,7 @@ function _mapStateToProps(state, ownProps) {
|
|||
if (participant) {
|
||||
avatar = getAvatarURL(participant);
|
||||
connectionStatus = participant.connectionStatus;
|
||||
participantName = getParticipantDisplayName(state);
|
||||
participantName = getParticipantDisplayName(state, participant.id);
|
||||
|
||||
// Avatar (on React Native) now has the ability to generate an
|
||||
// automatically-colored default image when no URI/URL is specified or
|
||||
|
|
|
@ -160,7 +160,8 @@ export function getParticipantCount(stateful: Object | Function) {
|
|||
* @returns {string}
|
||||
*/
|
||||
export function getParticipantDisplayName(
|
||||
stateful: Object | Function, id: string) {
|
||||
stateful: Object | Function,
|
||||
id: string) {
|
||||
const participant = getParticipantById(stateful, id);
|
||||
|
||||
if (participant) {
|
||||
|
|
|
@ -18,11 +18,11 @@ import {
|
|||
styles,
|
||||
VideoMutedIndicator
|
||||
} from './_';
|
||||
|
||||
import { AVATAR_SIZE } from './styles';
|
||||
|
||||
/**
|
||||
* React component for video thumbnail.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
class Thumbnail extends Component {
|
||||
|
|
|
@ -8,6 +8,9 @@ import { DimensionsDetector } from '../../base/responsive-ui';
|
|||
|
||||
import styles, { AVATAR_SIZE } from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} props of {@link LargeVideo}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
|
@ -18,6 +21,9 @@ type Props = {
|
|||
_participantId: string
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} state of {@link LargeVideo}.
|
||||
*/
|
||||
type State = {
|
||||
|
||||
/**
|
||||
|
@ -57,6 +63,7 @@ class LargeVideo extends Component<Props, State> {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onDimensionsChanged = this._onDimensionsChanged.bind(this);
|
||||
}
|
||||
|
||||
|
@ -75,19 +82,18 @@ class LargeVideo extends Component<Props, State> {
|
|||
_onDimensionsChanged(width: number, height: number) {
|
||||
// Get the size, rounded to the nearest even number.
|
||||
const size = 2 * Math.round(Math.min(height, width) / 2);
|
||||
|
||||
let newState;
|
||||
let nextState;
|
||||
|
||||
if (size < AVATAR_SIZE * 1.5) {
|
||||
newState = {
|
||||
nextState = {
|
||||
avatarSize: size - 15, // Leave some margin.
|
||||
useConnectivityInfoLabel: false
|
||||
};
|
||||
} else {
|
||||
newState = DEFAULT_STATE;
|
||||
nextState = DEFAULT_STATE;
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
this.setState(nextState);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue