[RN] Dynamically adjust LargeView's Avatar to available size
When in PiP mode the LargeView will not be large enough to hold the avatar (for those interested in the details, our avatar's size is 200, and in PiP mode the app is resized to about 150). In order to solve it, this PR refactors how the avatar style is passed along, reducing it to a single "size" prop. With this only prop, the Avatar compononent will compute the width, height and borderRadius, plus deal with some Android shenanigans. In addition, the LargeView component now uses DimensionsDetector to check its own size and adjust the size prop passed to the Avatar component as needed.
This commit is contained in:
committed by
Lyubo Marinov
parent
4fb37c38eb
commit
1419247801
@@ -1,12 +1,42 @@
|
||||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ParticipantView } from '../../base/participants';
|
||||
import { DimensionsDetector } from '../../base/responsive-ui';
|
||||
|
||||
import styles from './styles';
|
||||
import styles, { AVATAR_SIZE } from './styles';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The ID of the participant (to be) depicted by LargeVideo.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_participantId: string
|
||||
};
|
||||
|
||||
type State = {
|
||||
|
||||
/**
|
||||
* Size for the Avatar. It will be dynamically adjusted based on the
|
||||
* available size.
|
||||
*/
|
||||
avatarSize: number,
|
||||
|
||||
/**
|
||||
* Whether the connectivity indicator will be shown or not. It will be true
|
||||
* by default, but it may be turned off if there is not enough space.
|
||||
*/
|
||||
useConnectivityInfoLabel: boolean
|
||||
};
|
||||
|
||||
const DEFAULT_STATE = {
|
||||
avatarSize: AVATAR_SIZE,
|
||||
useConnectivityInfoLabel: true
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements a React {@link Component} which represents the large video (a.k.a.
|
||||
@@ -14,21 +44,52 @@ import styles from './styles';
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
class LargeVideo extends Component<*> {
|
||||
/**
|
||||
* LargeVideo component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
/**
|
||||
* The ID of the participant (to be) depicted by LargeVideo.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_participantId: PropTypes.string
|
||||
class LargeVideo extends Component<Props, State> {
|
||||
state = {
|
||||
...DEFAULT_STATE
|
||||
};
|
||||
|
||||
/** Initializes a new {@code LargeVideo} instance.
|
||||
*
|
||||
* @param {Object} props - The read-only properties with which the new
|
||||
* instance is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this._onDimensionsChanged = this._onDimensionsChanged.bind(this);
|
||||
}
|
||||
|
||||
_onDimensionsChanged: (width: number, height: number) => void;
|
||||
|
||||
/**
|
||||
* Handle this component's dimension changes. In case we deem it's too
|
||||
* small, the connectivity indicator won't be rendered and the avatar
|
||||
* will occupy the entirety of the available screen state.
|
||||
*
|
||||
* @param {number} width - The component's current width.
|
||||
* @param {number} height - The component's current height.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_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;
|
||||
|
||||
if (size < AVATAR_SIZE * 1.5) {
|
||||
newState = {
|
||||
avatarSize: size - 15, // Leave some margin.
|
||||
useConnectivityInfoLabel: false
|
||||
};
|
||||
} else {
|
||||
newState = DEFAULT_STATE;
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
@@ -36,13 +97,21 @@ class LargeVideo extends Component<*> {
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const {
|
||||
avatarSize,
|
||||
useConnectivityInfoLabel
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<ParticipantView
|
||||
avatarStyle = { styles.avatar }
|
||||
participantId = { this.props._participantId }
|
||||
style = { styles.largeVideo }
|
||||
useConnectivityInfoLabel = { true }
|
||||
zOrder = { 0 } />
|
||||
<DimensionsDetector
|
||||
onDimensionsChanged = { this._onDimensionsChanged } >
|
||||
<ParticipantView
|
||||
avatarSize = { avatarSize }
|
||||
participantId = { this.props._participantId }
|
||||
style = { styles.largeVideo }
|
||||
useConnectivityInfoLabel = { useConnectivityInfoLabel }
|
||||
zOrder = { 0 } />
|
||||
</DimensionsDetector>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
import { ColorPalette, createStyleSheet } from '../../base/styles';
|
||||
|
||||
export default createStyleSheet({
|
||||
/**
|
||||
* The style of the avatar of the participant displayed in largeVideo. It's
|
||||
* an addition to the default style of Avatar.
|
||||
*/
|
||||
avatar: {
|
||||
alignSelf: 'center',
|
||||
borderRadius: 100,
|
||||
flex: 0,
|
||||
height: 200,
|
||||
width: 200
|
||||
},
|
||||
/**
|
||||
* Size for the Avatar.
|
||||
*/
|
||||
export const AVATAR_SIZE = 200;
|
||||
|
||||
export default createStyleSheet({
|
||||
/**
|
||||
* Large video container style.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user