Call screen footer styling improvements
This commit is contained in:
parent
7e23bb6246
commit
66da943f27
8 changed files with 136 additions and 67 deletions
|
@ -5865,12 +5865,14 @@ button.module-image__border-overlay:focus {
|
|||
height: 100%;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
&--blur {
|
||||
position: absolute;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
filter: blur(25px);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
|
@ -6170,6 +6172,9 @@ button.module-image__border-overlay:focus {
|
|||
}
|
||||
|
||||
.module-ongoing-call {
|
||||
$local-preview-width: 136px;
|
||||
$local-preview-height: 102px;
|
||||
|
||||
&__remote-video-enabled {
|
||||
background-color: $color-gray-95;
|
||||
height: 100vh;
|
||||
|
@ -6185,16 +6190,6 @@ button.module-image__border-overlay:focus {
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
&__local-video {
|
||||
background-color: transparent;
|
||||
bottom: 160px;
|
||||
height: 152px;
|
||||
position: absolute;
|
||||
right: 32px;
|
||||
transform: rotateY(180deg);
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
&__header {
|
||||
position: absolute;
|
||||
}
|
||||
|
@ -6206,16 +6201,45 @@ button.module-image__border-overlay:focus {
|
|||
letter-spacing: -0.0025em;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
&__footer {
|
||||
background: linear-gradient(transparent, $color-black-alpha-40);
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-bottom: 32px;
|
||||
padding-top: 32px;
|
||||
justify-content: space-between;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
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 {
|
||||
|
|
|
@ -16,22 +16,20 @@ export const CallBackgroundBlur = ({
|
|||
children,
|
||||
color,
|
||||
}: PropsType): JSX.Element => {
|
||||
const backgroundProps = avatarPath
|
||||
? {
|
||||
style: {
|
||||
backgroundImage: `url("${avatarPath}")`,
|
||||
},
|
||||
}
|
||||
: {
|
||||
className: classNames(
|
||||
'module-calling__background',
|
||||
`module-background-color__${color || 'default'}`
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="module-calling__background">
|
||||
<div className="module-calling__background--blur" {...backgroundProps} />
|
||||
<div
|
||||
className={classNames('module-calling__background', {
|
||||
[`module-background-color__${color || 'default'}`]: !avatarPath,
|
||||
})}
|
||||
>
|
||||
{avatarPath && (
|
||||
<div
|
||||
className="module-calling__background--blur"
|
||||
style={{
|
||||
backgroundImage: `url("${avatarPath}")`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -40,6 +40,10 @@ const defaultProps = {
|
|||
hasLocalVideo: true,
|
||||
hasRemoteVideo: true,
|
||||
i18n,
|
||||
me: {
|
||||
color: 'ultramarine' as ColorType,
|
||||
title: 'Morty Smith',
|
||||
},
|
||||
pip: false,
|
||||
renderDeviceSelection: () => <div />,
|
||||
setLocalAudio: action('set-local-audio'),
|
||||
|
|
|
@ -45,6 +45,7 @@ export const CallManager = ({
|
|||
hasLocalVideo,
|
||||
hasRemoteVideo,
|
||||
i18n,
|
||||
me,
|
||||
pip,
|
||||
renderDeviceSelection,
|
||||
setLocalAudio,
|
||||
|
@ -130,6 +131,7 @@ export const CallManager = ({
|
|||
hasLocalAudio={hasLocalAudio}
|
||||
hasLocalVideo={hasLocalVideo}
|
||||
i18n={i18n}
|
||||
me={me}
|
||||
hasRemoteVideo={hasRemoteVideo}
|
||||
setLocalPreview={setLocalPreview}
|
||||
setRendererCanvas={setRendererCanvas}
|
||||
|
|
|
@ -44,6 +44,12 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
|||
overrideProps.hasRemoteVideo || false
|
||||
),
|
||||
i18n,
|
||||
me: {
|
||||
color: 'ultramarine' as ColorType,
|
||||
name: 'Morty Smith',
|
||||
profileName: 'Morty Smith',
|
||||
title: 'Morty Smith',
|
||||
},
|
||||
setLocalAudio: action('set-local-audio'),
|
||||
setLocalPreview: action('set-local-preview'),
|
||||
setLocalVideo: action('set-local-video'),
|
||||
|
|
|
@ -14,7 +14,9 @@ import {
|
|||
} from '../state/ducks/calling';
|
||||
import { Avatar } from './Avatar';
|
||||
import { CallingButton, CallingButtonType } from './CallingButton';
|
||||
import { CallBackgroundBlur } from './CallBackgroundBlur';
|
||||
import { CallState } from '../types/Calling';
|
||||
import { ColorType } from '../types/Colors';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
|
||||
export type PropsType = {
|
||||
|
@ -25,6 +27,14 @@ export type PropsType = {
|
|||
hasLocalVideo: boolean;
|
||||
hasRemoteVideo: boolean;
|
||||
i18n: LocalizerType;
|
||||
me: {
|
||||
avatarPath?: string;
|
||||
color?: ColorType;
|
||||
name?: string;
|
||||
phoneNumber?: string;
|
||||
profileName?: string;
|
||||
title: string;
|
||||
};
|
||||
setLocalAudio: (_: SetLocalAudioType) => void;
|
||||
setLocalVideo: (_: SetLocalVideoType) => void;
|
||||
setLocalPreview: (_: SetLocalPreviewType) => void;
|
||||
|
@ -41,6 +51,7 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
hasLocalVideo,
|
||||
hasRemoteVideo,
|
||||
i18n,
|
||||
me,
|
||||
setLocalAudio,
|
||||
setLocalVideo,
|
||||
setLocalPreview,
|
||||
|
@ -196,39 +207,61 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
) : (
|
||||
renderAvatar(i18n, callDetails)
|
||||
)}
|
||||
{hasLocalVideo && (
|
||||
<video
|
||||
className="module-ongoing-call__local-video"
|
||||
ref={localVideoRef}
|
||||
autoPlay
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={classNames(
|
||||
'module-ongoing-call__actions',
|
||||
controlsFadeClass
|
||||
)}
|
||||
>
|
||||
<CallingButton
|
||||
buttonType={videoButtonType}
|
||||
i18n={i18n}
|
||||
onClick={toggleVideo}
|
||||
tooltipDistance={24}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={audioButtonType}
|
||||
i18n={i18n}
|
||||
onClick={toggleAudio}
|
||||
tooltipDistance={24}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={CallingButtonType.HANG_UP}
|
||||
i18n={i18n}
|
||||
onClick={() => {
|
||||
hangUp({ callId });
|
||||
}}
|
||||
tooltipDistance={24}
|
||||
/>
|
||||
<div className="module-ongoing-call__footer">
|
||||
{/* This layout-only element is not ideal.
|
||||
See the comment in _modules.css for more. */}
|
||||
<div className="module-ongoing-call__footer__local-preview-offset" />
|
||||
<div
|
||||
className={classNames(
|
||||
'module-ongoing-call__footer__actions',
|
||||
controlsFadeClass
|
||||
)}
|
||||
>
|
||||
<CallingButton
|
||||
buttonType={videoButtonType}
|
||||
i18n={i18n}
|
||||
onClick={toggleVideo}
|
||||
tooltipDistance={24}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={audioButtonType}
|
||||
i18n={i18n}
|
||||
onClick={toggleAudio}
|
||||
tooltipDistance={24}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={CallingButtonType.HANG_UP}
|
||||
i18n={i18n}
|
||||
onClick={() => {
|
||||
hangUp({ callId });
|
||||
}}
|
||||
tooltipDistance={24}
|
||||
/>
|
||||
</div>
|
||||
<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>
|
||||
);
|
||||
|
|
|
@ -5,6 +5,7 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { mapDispatchToProps } from '../actions';
|
||||
import { CallManager } from '../../components/CallManager';
|
||||
import { getMe } from '../selectors/conversations';
|
||||
import { StateType } from '../reducer';
|
||||
|
||||
import { getIntl } from '../selectors/user';
|
||||
|
@ -20,6 +21,7 @@ const mapStateToProps = (state: StateType) => {
|
|||
return {
|
||||
...calling,
|
||||
i18n: getIntl(state),
|
||||
me: getMe(state),
|
||||
renderDeviceSelection,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -14391,7 +14391,7 @@
|
|||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallScreen.js",
|
||||
"line": " const localVideoRef = react_1.useRef(null);",
|
||||
"lineNumber": 43,
|
||||
"lineNumber": 44,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T21:35:52.858Z",
|
||||
"reasonDetail": "Used to get the local video element for rendering."
|
||||
|
@ -14400,7 +14400,7 @@
|
|||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallScreen.js",
|
||||
"line": " const remoteVideoRef = react_1.useRef(null);",
|
||||
"lineNumber": 44,
|
||||
"lineNumber": 45,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T21:35:52.858Z",
|
||||
"reasonDetail": "Used to get the remote video element for rendering."
|
||||
|
@ -15142,4 +15142,4 @@
|
|||
"reasonCategory": "falseMatch",
|
||||
"updated": "2020-09-08T23:07:22.682Z"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
Loading…
Add table
Reference in a new issue