From 4f52a2912055aa833fc0f51b08d13e215570d296 Mon Sep 17 00:00:00 2001 From: Vlad Piersec Date: Fri, 7 Aug 2020 14:46:24 +0300 Subject: [PATCH] fix(prejoin): Make avatar resizable --- css/_premeeting-screens.scss | 9 +-- .../base/premeeting/components/web/Avatar.js | 61 ++++++++++++++++ .../base/premeeting/components/web/Preview.js | 11 +-- react/features/base/premeeting/functions.js | 73 ++++++++++++++++++- 4 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 react/features/base/premeeting/components/web/Avatar.js diff --git a/css/_premeeting-screens.scss b/css/_premeeting-screens.scss index c892100d6..f2164b00b 100644 --- a/css/_premeeting-screens.scss +++ b/css/_premeeting-screens.scss @@ -197,16 +197,9 @@ text-align: center; } - .preview-avatar-container { - width: 100%; - height: 80%; - display: flex; - align-items: center; - justify-content: center; - } - .avatar { background: #A4B8D1; + margin: 0 auto; } video { diff --git a/react/features/base/premeeting/components/web/Avatar.js b/react/features/base/premeeting/components/web/Avatar.js new file mode 100644 index 000000000..03531f9cc --- /dev/null +++ b/react/features/base/premeeting/components/web/Avatar.js @@ -0,0 +1,61 @@ +// @flow + +import React from 'react'; + +import { Avatar } from '../../../avatar'; +import { connect } from '../../../redux'; +import { calculateAvatarDimensions } from '../../functions'; + +type Props = { + + /** + * The height of the window. + */ + height: number, + + /** + * The name of the participant (if any). + */ + name: string +} + +/** + * Component displaying the avatar for the premeeting screen. + * + * @param {Props} props - The props of the component. + * @returns {ReactElement} + */ +function PremeetingAvatar({ height, name }: Props) { + const { marginTop, size } = calculateAvatarDimensions(height); + + if (size <= 5) { + return null; + } + + + return ( +
+ +
+ ); +} + +/** + * Maps (parts of) the redux state to the React {@code Component} props. + * + * @param {Object} state - The redux state. + * @returns {{ + * height: number + * }} + */ +function mapStateToProps(state) { + return { + height: state['features/base/responsive-ui'].clientHeight + }; +} + +export default connect(mapStateToProps)(PremeetingAvatar); diff --git a/react/features/base/premeeting/components/web/Preview.js b/react/features/base/premeeting/components/web/Preview.js index 7dae4675e..c3330fe7c 100644 --- a/react/features/base/premeeting/components/web/Preview.js +++ b/react/features/base/premeeting/components/web/Preview.js @@ -2,11 +2,12 @@ import React from 'react'; -import { Avatar } from '../../../avatar'; import { Video } from '../../../media'; import { connect } from '../../../redux'; import { getLocalVideoTrack } from '../../../tracks'; +import PreviewAvatar from './Avatar'; + export type Props = { /** @@ -54,13 +55,7 @@ function Preview(props: Props) {
-
- -
+
); } diff --git a/react/features/base/premeeting/functions.js b/react/features/base/premeeting/functions.js index ff088abe0..43b7b9cc8 100644 --- a/react/features/base/premeeting/functions.js +++ b/react/features/base/premeeting/functions.js @@ -1,3 +1,5 @@ +// @flow + import { findIndex } from 'lodash'; import { CONNECTION_TYPE } from './constants'; @@ -8,6 +10,75 @@ const LOSS_VIDEO_THRESHOLDS = [ 0.33, 0.1, 0.05 ]; const THROUGHPUT_AUDIO_THRESHOLDS = [ 8, 20 ]; const THROUGHPUT_VIDEO_THRESHOLDS = [ 60, 750 ]; +/** + * The avatar size to container size ration. + */ +const ratio = 1 / 3; + +/** + * The max avatar size. + */ +const maxSize = 190; + +/** + * The window limit hight over which the avatar should have the default dimension. + */ +const upperHeightLimit = 760; + +/** + * The window limit hight under which the avatar should not be resized anymore. + */ +const lowerHeightLimit = 460; + +/** + * The default top margin of the avatar. + */ +const defaultMarginTop = '10%'; + +/** + * The top margin of the avatar when its dimension is small. + */ +const smallMarginTop = '5%'; + +/** + * Calculates avatar dimensions based on window height and position. + * + * @param {number} height - The window height. + * @returns {{ + * marginTop: string, + * size: number + * }} + */ +export function calculateAvatarDimensions(height: number) { + if (height > upperHeightLimit) { + return { + size: maxSize, + marginTop: defaultMarginTop + }; + } + + if (height > lowerHeightLimit) { + const diff = height - lowerHeightLimit; + const percent = diff * ratio; + const size = Math.floor(maxSize * percent / 100); + let marginTop = defaultMarginTop; + + if (height < 600) { + marginTop = smallMarginTop; + } + + return { + size, + marginTop + }; + } + + return { + size: 0, + marginTop: '0' + }; +} + /** * Returns the level based on a list of thresholds. * @@ -121,7 +192,7 @@ function _getConnectionDataFromTestResults({ fractionalLoss: l, throughput: t }) * connectionDetails: string[] * }} */ -export function getConnectionData(state) { +export function getConnectionData(state: Object) { const { precallTestResults } = state['features/prejoin']; if (precallTestResults) {