diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss
index 1c07abfa72..f605556e79 100644
--- a/stylesheets/_modules.scss
+++ b/stylesheets/_modules.scss
@@ -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 {
diff --git a/ts/components/CallBackgroundBlur.tsx b/ts/components/CallBackgroundBlur.tsx
index 5189d85fa5..a085b3fc91 100644
--- a/ts/components/CallBackgroundBlur.tsx
+++ b/ts/components/CallBackgroundBlur.tsx
@@ -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 (
-
-
+
+ {avatarPath && (
+
+ )}
{children}
);
diff --git a/ts/components/CallManager.stories.tsx b/ts/components/CallManager.stories.tsx
index 2ec14c4534..055125b42a 100644
--- a/ts/components/CallManager.stories.tsx
+++ b/ts/components/CallManager.stories.tsx
@@ -40,6 +40,10 @@ const defaultProps = {
hasLocalVideo: true,
hasRemoteVideo: true,
i18n,
+ me: {
+ color: 'ultramarine' as ColorType,
+ title: 'Morty Smith',
+ },
pip: false,
renderDeviceSelection: () =>
,
setLocalAudio: action('set-local-audio'),
diff --git a/ts/components/CallManager.tsx b/ts/components/CallManager.tsx
index dea3907a6c..983789ee47 100644
--- a/ts/components/CallManager.tsx
+++ b/ts/components/CallManager.tsx
@@ -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}
diff --git a/ts/components/CallScreen.stories.tsx b/ts/components/CallScreen.stories.tsx
index fef4997ed7..769586c013 100644
--- a/ts/components/CallScreen.stories.tsx
+++ b/ts/components/CallScreen.stories.tsx
@@ -44,6 +44,12 @@ const createProps = (overrideProps: Partial
= {}): 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'),
diff --git a/ts/components/CallScreen.tsx b/ts/components/CallScreen.tsx
index d249714c04..d2e5241f3f 100644
--- a/ts/components/CallScreen.tsx
+++ b/ts/components/CallScreen.tsx
@@ -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 = ({
hasLocalVideo,
hasRemoteVideo,
i18n,
+ me,
setLocalAudio,
setLocalVideo,
setLocalPreview,
@@ -196,39 +207,61 @@ export const CallScreen: React.FC = ({
) : (
renderAvatar(i18n, callDetails)
)}
- {hasLocalVideo && (
-
- )}
-
-
-
-
{
- hangUp({ callId });
- }}
- tooltipDistance={24}
- />
+
+ {/* This layout-only element is not ideal.
+ See the comment in _modules.css for more. */}
+
+
+
+
+ {
+ hangUp({ callId });
+ }}
+ tooltipDistance={24}
+ />
+
+
+ {hasLocalVideo ? (
+
+ ) : (
+
+
+
+ )}
+
);
diff --git a/ts/state/smart/CallManager.tsx b/ts/state/smart/CallManager.tsx
index 0de28fae4b..432dde958a 100644
--- a/ts/state/smart/CallManager.tsx
+++ b/ts/state/smart/CallManager.tsx
@@ -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,
};
};
diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json
index 6e78e72685..0a62d7c0d6 100644
--- a/ts/util/lint/exceptions.json
+++ b/ts/util/lint/exceptions.json
@@ -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"
}
-]
\ No newline at end of file
+]