Call screen footer styling improvements

This commit is contained in:
Evan Hahn 2020-11-04 13:56:03 -06:00 committed by GitHub
parent 7e23bb6246
commit 66da943f27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 136 additions and 67 deletions

View file

@ -5865,12 +5865,14 @@ button.module-image__border-overlay:focus {
height: 100%; height: 100%;
justify-content: center; justify-content: center;
overflow: hidden; overflow: hidden;
position: absolute; position: relative;
width: 100%; width: 100%;
&--blur { &--blur {
position: absolute;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
background-position: center;
filter: blur(25px); filter: blur(25px);
height: 100%; height: 100%;
position: absolute; position: absolute;
@ -6170,6 +6172,9 @@ button.module-image__border-overlay:focus {
} }
.module-ongoing-call { .module-ongoing-call {
$local-preview-width: 136px;
$local-preview-height: 102px;
&__remote-video-enabled { &__remote-video-enabled {
background-color: $color-gray-95; background-color: $color-gray-95;
height: 100vh; height: 100vh;
@ -6185,16 +6190,6 @@ button.module-image__border-overlay:focus {
justify-content: center; justify-content: center;
} }
&__local-video {
background-color: transparent;
bottom: 160px;
height: 152px;
position: absolute;
right: 32px;
transform: rotateY(180deg);
width: 210px;
}
&__header { &__header {
position: absolute; position: absolute;
} }
@ -6206,16 +6201,45 @@ button.module-image__border-overlay:focus {
letter-spacing: -0.0025em; letter-spacing: -0.0025em;
} }
&__actions { &__footer {
background: linear-gradient(transparent, $color-black-alpha-40); background: linear-gradient(transparent, $color-black-alpha-40);
bottom: 0; bottom: 0;
display: flex; display: flex;
justify-content: center; justify-content: space-between;
padding-bottom: 32px;
padding-top: 32px;
position: absolute; position: absolute;
text-align: center;
width: 100%; width: 100%;
&__actions {
align-items: center;
display: flex;
flex-grow: 1;
justify-content: center;
}
// This layout-only element is not ideal, but lets us keep the actions centered until
// until they'd overlap with the video, at which point they start to move.
&__local-preview-offset {
flex: 1 0;
max-width: $local-preview-width;
visibility: hidden;
}
&__local-preview {
border-radius: 5px;
display: flex;
height: $local-preview-height;
margin: 2px 16px 16px 0;
overflow: hidden;
width: $local-preview-width;
&__video {
// The background-color is seen while the video loads.
background-color: $color-gray-75;
height: 100%;
transform: rotateY(180deg);
width: 100%;
}
}
} }
&__controls--fadeIn { &__controls--fadeIn {

View file

@ -16,22 +16,20 @@ export const CallBackgroundBlur = ({
children, children,
color, color,
}: PropsType): JSX.Element => { }: PropsType): JSX.Element => {
const backgroundProps = avatarPath
? {
style: {
backgroundImage: `url("${avatarPath}")`,
},
}
: {
className: classNames(
'module-calling__background',
`module-background-color__${color || 'default'}`
),
};
return ( return (
<div className="module-calling__background"> <div
<div className="module-calling__background--blur" {...backgroundProps} /> className={classNames('module-calling__background', {
[`module-background-color__${color || 'default'}`]: !avatarPath,
})}
>
{avatarPath && (
<div
className="module-calling__background--blur"
style={{
backgroundImage: `url("${avatarPath}")`,
}}
/>
)}
{children} {children}
</div> </div>
); );

View file

@ -40,6 +40,10 @@ const defaultProps = {
hasLocalVideo: true, hasLocalVideo: true,
hasRemoteVideo: true, hasRemoteVideo: true,
i18n, i18n,
me: {
color: 'ultramarine' as ColorType,
title: 'Morty Smith',
},
pip: false, pip: false,
renderDeviceSelection: () => <div />, renderDeviceSelection: () => <div />,
setLocalAudio: action('set-local-audio'), setLocalAudio: action('set-local-audio'),

View file

@ -45,6 +45,7 @@ export const CallManager = ({
hasLocalVideo, hasLocalVideo,
hasRemoteVideo, hasRemoteVideo,
i18n, i18n,
me,
pip, pip,
renderDeviceSelection, renderDeviceSelection,
setLocalAudio, setLocalAudio,
@ -130,6 +131,7 @@ export const CallManager = ({
hasLocalAudio={hasLocalAudio} hasLocalAudio={hasLocalAudio}
hasLocalVideo={hasLocalVideo} hasLocalVideo={hasLocalVideo}
i18n={i18n} i18n={i18n}
me={me}
hasRemoteVideo={hasRemoteVideo} hasRemoteVideo={hasRemoteVideo}
setLocalPreview={setLocalPreview} setLocalPreview={setLocalPreview}
setRendererCanvas={setRendererCanvas} setRendererCanvas={setRendererCanvas}

View file

@ -44,6 +44,12 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
overrideProps.hasRemoteVideo || false overrideProps.hasRemoteVideo || false
), ),
i18n, i18n,
me: {
color: 'ultramarine' as ColorType,
name: 'Morty Smith',
profileName: 'Morty Smith',
title: 'Morty Smith',
},
setLocalAudio: action('set-local-audio'), setLocalAudio: action('set-local-audio'),
setLocalPreview: action('set-local-preview'), setLocalPreview: action('set-local-preview'),
setLocalVideo: action('set-local-video'), setLocalVideo: action('set-local-video'),

View file

@ -14,7 +14,9 @@ import {
} from '../state/ducks/calling'; } from '../state/ducks/calling';
import { Avatar } from './Avatar'; import { Avatar } from './Avatar';
import { CallingButton, CallingButtonType } from './CallingButton'; import { CallingButton, CallingButtonType } from './CallingButton';
import { CallBackgroundBlur } from './CallBackgroundBlur';
import { CallState } from '../types/Calling'; import { CallState } from '../types/Calling';
import { ColorType } from '../types/Colors';
import { LocalizerType } from '../types/Util'; import { LocalizerType } from '../types/Util';
export type PropsType = { export type PropsType = {
@ -25,6 +27,14 @@ export type PropsType = {
hasLocalVideo: boolean; hasLocalVideo: boolean;
hasRemoteVideo: boolean; hasRemoteVideo: boolean;
i18n: LocalizerType; i18n: LocalizerType;
me: {
avatarPath?: string;
color?: ColorType;
name?: string;
phoneNumber?: string;
profileName?: string;
title: string;
};
setLocalAudio: (_: SetLocalAudioType) => void; setLocalAudio: (_: SetLocalAudioType) => void;
setLocalVideo: (_: SetLocalVideoType) => void; setLocalVideo: (_: SetLocalVideoType) => void;
setLocalPreview: (_: SetLocalPreviewType) => void; setLocalPreview: (_: SetLocalPreviewType) => void;
@ -41,6 +51,7 @@ export const CallScreen: React.FC<PropsType> = ({
hasLocalVideo, hasLocalVideo,
hasRemoteVideo, hasRemoteVideo,
i18n, i18n,
me,
setLocalAudio, setLocalAudio,
setLocalVideo, setLocalVideo,
setLocalPreview, setLocalPreview,
@ -196,39 +207,61 @@ export const CallScreen: React.FC<PropsType> = ({
) : ( ) : (
renderAvatar(i18n, callDetails) renderAvatar(i18n, callDetails)
)} )}
{hasLocalVideo && ( <div className="module-ongoing-call__footer">
<video {/* This layout-only element is not ideal.
className="module-ongoing-call__local-video" See the comment in _modules.css for more. */}
ref={localVideoRef} <div className="module-ongoing-call__footer__local-preview-offset" />
autoPlay <div
/> className={classNames(
)} 'module-ongoing-call__footer__actions',
<div controlsFadeClass
className={classNames( )}
'module-ongoing-call__actions', >
controlsFadeClass <CallingButton
)} buttonType={videoButtonType}
> i18n={i18n}
<CallingButton onClick={toggleVideo}
buttonType={videoButtonType} tooltipDistance={24}
i18n={i18n} />
onClick={toggleVideo} <CallingButton
tooltipDistance={24} buttonType={audioButtonType}
/> i18n={i18n}
<CallingButton onClick={toggleAudio}
buttonType={audioButtonType} tooltipDistance={24}
i18n={i18n} />
onClick={toggleAudio} <CallingButton
tooltipDistance={24} buttonType={CallingButtonType.HANG_UP}
/> i18n={i18n}
<CallingButton onClick={() => {
buttonType={CallingButtonType.HANG_UP} hangUp({ callId });
i18n={i18n} }}
onClick={() => { tooltipDistance={24}
hangUp({ callId }); />
}} </div>
tooltipDistance={24} <div className="module-ongoing-call__footer__local-preview">
/> {hasLocalVideo ? (
<video
className="module-ongoing-call__footer__local-preview__video"
ref={localVideoRef}
autoPlay
/>
) : (
<CallBackgroundBlur avatarPath={me.avatarPath} color={me.color}>
<Avatar
avatarPath={me.avatarPath}
color={me.color || 'ultramarine'}
noteToSelf={false}
conversationType="direct"
i18n={i18n}
name={me.name}
phoneNumber={me.phoneNumber}
profileName={me.profileName}
title={me.title}
size={80}
/>
</CallBackgroundBlur>
)}
</div>
</div> </div>
</div> </div>
); );

View file

@ -5,6 +5,7 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { mapDispatchToProps } from '../actions'; import { mapDispatchToProps } from '../actions';
import { CallManager } from '../../components/CallManager'; import { CallManager } from '../../components/CallManager';
import { getMe } from '../selectors/conversations';
import { StateType } from '../reducer'; import { StateType } from '../reducer';
import { getIntl } from '../selectors/user'; import { getIntl } from '../selectors/user';
@ -20,6 +21,7 @@ const mapStateToProps = (state: StateType) => {
return { return {
...calling, ...calling,
i18n: getIntl(state), i18n: getIntl(state),
me: getMe(state),
renderDeviceSelection, renderDeviceSelection,
}; };
}; };

View file

@ -14391,7 +14391,7 @@
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/CallScreen.js", "path": "ts/components/CallScreen.js",
"line": " const localVideoRef = react_1.useRef(null);", "line": " const localVideoRef = react_1.useRef(null);",
"lineNumber": 43, "lineNumber": 44,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-10-26T21:35:52.858Z", "updated": "2020-10-26T21:35:52.858Z",
"reasonDetail": "Used to get the local video element for rendering." "reasonDetail": "Used to get the local video element for rendering."
@ -14400,7 +14400,7 @@
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/CallScreen.js", "path": "ts/components/CallScreen.js",
"line": " const remoteVideoRef = react_1.useRef(null);", "line": " const remoteVideoRef = react_1.useRef(null);",
"lineNumber": 44, "lineNumber": 45,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-10-26T21:35:52.858Z", "updated": "2020-10-26T21:35:52.858Z",
"reasonDetail": "Used to get the remote video element for rendering." "reasonDetail": "Used to get the remote video element for rendering."
@ -15142,4 +15142,4 @@
"reasonCategory": "falseMatch", "reasonCategory": "falseMatch",
"updated": "2020-09-08T23:07:22.682Z" "updated": "2020-09-08T23:07:22.682Z"
} }
] ]