feat(prejoin) improve ux

This commit is contained in:
Tudor-Ovidiu Avram
2020-09-29 14:00:30 +03:00
committed by Saúl Ibarra Corretgé
parent 9f9e192c3c
commit 478f1a731e
15 changed files with 135 additions and 245 deletions

View File

@@ -37,6 +37,11 @@ export type Props = {
*/
displayName?: string,
/**
* Whether or not to update the background color of the avatar
*/
dynamicColor?: Boolean,
/**
* ID of the element, if any.
*/
@@ -78,6 +83,15 @@ export const DEFAULT_SIZE = 65;
* Implements a class to render avatars in the app.
*/
class Avatar<P: Props> extends PureComponent<P, State> {
/**
* Default values for {@code Avatar} component's properties.
*
* @static
*/
static defaultProps = {
dynamicColor: true
};
/**
* Instantiates a new {@code Component}.
*
@@ -123,6 +137,7 @@ class Avatar<P: Props> extends PureComponent<P, State> {
_loadableAvatarUrl,
className,
colorBase,
dynamicColor,
id,
size,
status,
@@ -156,7 +171,10 @@ class Avatar<P: Props> extends PureComponent<P, State> {
const initials = getInitials(_initialsBase);
if (initials) {
avatarProps.color = getAvatarColor(colorBase || _initialsBase);
if (dynamicColor) {
avatarProps.color = getAvatarColor(colorBase || _initialsBase);
}
avatarProps.initials = initials;
}

View File

@@ -0,0 +1,3 @@
<svg width="10" height="7" viewBox="0 0 10 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.41115 6.05746C8.71903 6.39955 9.24594 6.42729 9.58803 6.1194C9.93012 5.81152 9.95786 5.28461 9.64997 4.94252L5.72917 0.562752C5.39813 0.194935 4.82138 0.194935 4.49034 0.562752L0.63061 4.94252C0.322728 5.28461 0.35046 5.81152 0.692552 6.1194C1.03464 6.42729 1.56155 6.39955 1.86943 6.05746L5.10975 2.36593L8.41115 6.05746Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 492 B

View File

@@ -5,6 +5,7 @@ export { default as IconAddPeople } from './link.svg';
export { default as IconArrowBack } from './arrow_back.svg';
export { default as IconArrowDown } from './arrow_down.svg';
export { default as IconArrowDownSmall } from './arrow-down-small.svg';
export { default as IconArrowUp } from './arrow_up.svg';
export { default as IconArrowLeft } from './arrow-left.svg';
export { default as IconAudioOnly } from './visibility.svg';
export { default as IconAudioOnlyOff } from './visibility-off.svg';

View File

@@ -26,6 +26,11 @@ type Props = {
*/
hasOptions?: boolean,
/**
* Icon to display in the options section.
*/
OptionsIcon?: React$Node,
/**
* TestId of the button. Can be used to locate element when testing UI.
*/
@@ -57,6 +62,7 @@ function ActionButton({
className = '',
disabled,
hasOptions,
OptionsIcon = IconArrowDown,
testId,
type = 'primary',
onClick,
@@ -75,7 +81,7 @@ function ActionButton({
<Icon
className = 'icon'
size = { 14 }
src = { IconArrowDown } />
src = { OptionsIcon } />
</div>
}
</div>

View File

@@ -1,61 +0,0 @@
// @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 (
<div style = {{ marginTop }}>
<Avatar
className = 'preview-avatar'
displayName = { name }
participantId = 'local'
size = { size } />
</div>
);
}
/**
* 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);

View File

@@ -61,6 +61,9 @@ function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
? 'con-status-arrow con-status-arrow--up'
: 'con-status-arrow';
const detailsText = connectionDetails.map(t).join(' ');
const detailsClassName = showDetails
? 'con-status-details-visible'
: 'con-status-details-hidden';
return (
<div className = 'con-status'>
@@ -79,8 +82,7 @@ function ConnectionStatus({ connectionDetails, t, connectionType }: Props) {
size = { 24 }
src = { IconArrowDownSmall } />
</div>
{ showDetails
&& <div className = 'con-status-details'>{detailsText}</div> }
<div className = { `con-status-details ${detailsClassName}` }>{detailsText}</div>
</div>
</div>
);

View File

@@ -3,6 +3,7 @@
import React, { PureComponent } from 'react';
import { AudioSettingsButton, VideoSettingsButton } from '../../../../toolbox/components/web';
import { Avatar } from '../../../avatar';
import ConnectionStatus from './ConnectionStatus';
import CopyMeetingUrl from './CopyMeetingUrl';
@@ -85,12 +86,18 @@ export default class PreMeetingScreen extends PureComponent<Props> {
id = 'lobby-screen'>
<ConnectionStatus />
<Preview
name = { name }
showAvatar = { showAvatar }
videoMuted = { videoMuted }
videoTrack = { videoTrack } />
{!videoMuted && <div className = 'preview-overlay' />}
<div className = 'content'>
{showAvatar && videoMuted && (
<Avatar
className = 'premeeting-screen-avatar'
displayName = { name }
dynamicColor = { false }
participantId = 'local'
size = { 80 } />
)}
{showConferenceInfo && (
<>
<div className = 'title'>

View File

@@ -6,20 +6,8 @@ import { Video } from '../../../media';
import { connect } from '../../../redux';
import { getLocalVideoTrack } from '../../../tracks';
import PreviewAvatar from './Avatar';
export type Props = {
/**
* The name of the user that is about to join.
*/
name: string,
/**
* Indicates whether the avatar should be shown when video is off
*/
showAvatar: boolean,
/**
* Flag signaling the visibility of camera preview.
*/
@@ -38,7 +26,7 @@ export type Props = {
* @returns {ReactElement}
*/
function Preview(props: Props) {
const { name, showAvatar, videoMuted, videoTrack } = props;
const { videoMuted, videoTrack } = props;
if (!videoMuted && videoTrack) {
return (
@@ -50,23 +38,9 @@ function Preview(props: Props) {
);
}
if (showAvatar) {
return (
<div
className = 'no-video'
id = 'preview'>
<PreviewAvatar name = { name } />
</div>
);
}
return null;
}
Preview.defaultProps = {
showAvatar: true
};
/**
* Maps part of the Redux state to the props of this component.
*