From 8446b2dc611c86f046617e0c78455976d11471f2 Mon Sep 17 00:00:00 2001 From: Josh Perez <60019601+josh-signal@users.noreply.github.com> Date: Wed, 14 Oct 2020 12:30:50 -0400 Subject: [PATCH] Calling: Match buttons in other clients --- _locales/en/messages.json | 8 ++++ stylesheets/_modules.scss | 62 ++++++++++++++++++------- ts/components/CallManager.stories.tsx | 1 + ts/components/CallManager.tsx | 3 ++ ts/components/CallingButton.stories.tsx | 14 ++++++ ts/components/CallingButton.tsx | 16 +++++-- ts/components/CallingLobby.stories.tsx | 25 ++++++++++ ts/components/CallingLobby.tsx | 7 ++- 8 files changed, 113 insertions(+), 23 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index c7c4ff9c81..10bc9e40d8 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1158,6 +1158,10 @@ "message": "Join Call", "description": "Button label in the call lobby for joining a call" }, + "calling__button--video-disabled": { + "message": "Camera disabled", + "description": "Button tooltip label when the camera is disabled" + }, "calling__button--video-off": { "message": "Turn off camera", "description": "Button tooltip label for turning off the camera" @@ -1166,6 +1170,10 @@ "message": "Turn on camera", "description": "Button tooltip label for turning on the camera" }, + "calling__button--audio-disabled": { + "message": "Microphone disabled", + "description": "Button tooltip label when the microphone is disabled" + }, "calling__button--audio-off": { "message": "Turn off microphone", "description": "Button tooltip label for turning off the microphone" diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss index 22e0b8a686..83ef2a02ed 100644 --- a/stylesheets/_modules.scss +++ b/stylesheets/_modules.scss @@ -6060,36 +6060,24 @@ button.module-image__border-overlay:focus { width: 56px; &--audio { - &--enabled { - background-color: $color-gray-45; - - div { - @include color-svg('../images/icons/v2/mic-solid-28.svg', $color-white); - height: 28px; - width: 28px; - } - } - &--disabled { + &--on { background-color: $color-white; div { @include color-svg( - '../images/icons/v2/mic-off-solid-28.svg', - $color-black + '../images/icons/v2/mic-solid-28.svg', + $color-gray-75 ); height: 28px; width: 28px; } } - } - - &--video { - &--enabled { + &--off { background-color: $color-gray-45; div { @include color-svg( - '../images/icons/v2/video-solid-28.svg', + '../images/icons/v2/mic-off-solid-28.svg', $color-white ); height: 28px; @@ -6097,12 +6085,50 @@ button.module-image__border-overlay:focus { } } &--disabled { + background-color: $color-gray-45; + opacity: 0.2; + + div { + @include color-svg('../images/icons/v2/mic-solid-28.svg', $color-white); + height: 28px; + width: 28px; + } + } + } + + &--video { + &--on { background-color: $color-white; + div { + @include color-svg( + '../images/icons/v2/video-solid-28.svg', + $color-gray-75 + ); + height: 28px; + width: 28px; + } + } + &--off { + background-color: $color-gray-45; + div { @include color-svg( '../images/icons/v2/video-off-solid-28.svg', - $color-black + $color-white + ); + height: 28px; + width: 28px; + } + } + &--disabled { + background-color: $color-gray-45; + opacity: 0.2; + + div { + @include color-svg( + '../images/icons/v2/video-solid-28.svg', + $color-white ); height: 28px; width: 28px; diff --git a/ts/components/CallManager.stories.tsx b/ts/components/CallManager.stories.tsx index 258677b05a..e5d68c8874 100644 --- a/ts/components/CallManager.stories.tsx +++ b/ts/components/CallManager.stories.tsx @@ -25,6 +25,7 @@ const callDetails = { }; const defaultProps = { + availableCameras: [], acceptCall: action('accept-call'), callDetails, callState: CallState.Accepted, diff --git a/ts/components/CallManager.tsx b/ts/components/CallManager.tsx index 6168175242..19c4216329 100644 --- a/ts/components/CallManager.tsx +++ b/ts/components/CallManager.tsx @@ -11,6 +11,7 @@ import { CallState, CallEndedReason } from '../types/Calling'; import { CallDetailsType, OutgoingCallType } from '../state/ducks/calling'; type CallManagerPropsType = { + availableCameras: Array; callDetails?: CallDetailsType; callEndedReason?: CallEndedReason; callState?: CallState; @@ -29,6 +30,7 @@ type PropsType = IncomingCallBarPropsType & export const CallManager = ({ acceptCall, + availableCameras, callDetails, callState, callEndedReason, @@ -79,6 +81,7 @@ export const CallManager = ({ return ( <> { return ; }); +story.add('Audio Disabled', () => { + const props = createProps({ + buttonType: CallingButtonType.AUDIO_DISABLED, + }); + return ; +}); + story.add('Video On', () => { const props = createProps({ buttonType: CallingButtonType.VIDEO_ON, @@ -68,6 +75,13 @@ story.add('Video Off', () => { return ; }); +story.add('Video Disabled', () => { + const props = createProps({ + buttonType: CallingButtonType.VIDEO_DISABLED, + }); + return ; +}); + story.add('Tooltip right', () => { const props = createProps({ tooltipDirection: TooltipDirection.RIGHT, diff --git a/ts/components/CallingButton.tsx b/ts/components/CallingButton.tsx index ddeda65619..e93b86bee3 100644 --- a/ts/components/CallingButton.tsx +++ b/ts/components/CallingButton.tsx @@ -11,9 +11,11 @@ export enum TooltipDirection { } export enum CallingButtonType { + AUDIO_DISABLED = 'AUDIO_DISABLED', AUDIO_OFF = 'AUDIO_OFF', AUDIO_ON = 'AUDIO_ON', HANG_UP = 'HANG_UP', + VIDEO_DISABLED = 'VIDEO_DISABLED', VIDEO_OFF = 'VIDEO_OFF', VIDEO_ON = 'VIDEO_ON', } @@ -35,17 +37,23 @@ export const CallingButton = ({ }: PropsType): JSX.Element => { let classNameSuffix = ''; let tooltipContent = ''; - if (buttonType === CallingButtonType.AUDIO_OFF) { + if (buttonType === CallingButtonType.AUDIO_DISABLED) { classNameSuffix = 'audio--disabled'; + tooltipContent = i18n('calling__button--audio-disabled'); + } else if (buttonType === CallingButtonType.AUDIO_OFF) { + classNameSuffix = 'audio--off'; tooltipContent = i18n('calling__button--audio-on'); } else if (buttonType === CallingButtonType.AUDIO_ON) { - classNameSuffix = 'audio--enabled'; + classNameSuffix = 'audio--on'; tooltipContent = i18n('calling__button--audio-off'); - } else if (buttonType === CallingButtonType.VIDEO_OFF) { + } else if (buttonType === CallingButtonType.VIDEO_DISABLED) { classNameSuffix = 'video--disabled'; + tooltipContent = i18n('calling__button--video-disabled'); + } else if (buttonType === CallingButtonType.VIDEO_OFF) { + classNameSuffix = 'video--off'; tooltipContent = i18n('calling__button--video-on'); } else if (buttonType === CallingButtonType.VIDEO_ON) { - classNameSuffix = 'video--enabled'; + classNameSuffix = 'video--on'; tooltipContent = i18n('calling__button--video-off'); } else if (buttonType === CallingButtonType.HANG_UP) { classNameSuffix = 'hangup'; diff --git a/ts/components/CallingLobby.stories.tsx b/ts/components/CallingLobby.stories.tsx index 0a6faff6da..f56f07025b 100644 --- a/ts/components/CallingLobby.stories.tsx +++ b/ts/components/CallingLobby.stories.tsx @@ -24,7 +24,18 @@ const callDetails = { profileName: 'Rick Sanchez', }; +const camera = { + deviceId: 'dfbe6effe70b0611ba0fdc2a9ea3f39f6cb110e6687948f7e5f016c111b7329c', + groupId: '63ee218d2446869e40adfc958ff98263e51f74382b0143328ee4826f20a76f47', + kind: 'videoinput' as MediaDeviceKind, + label: 'FaceTime HD Camera (Built-in) (9fba:bced)', + toJSON() { + return ''; + }, +}; + const createProps = (overrideProps: Partial = {}): PropsType => ({ + availableCameras: overrideProps.availableCameras || [camera], callDetails, hasLocalAudio: boolean('hasLocalAudio', overrideProps.hasLocalAudio || false), hasLocalVideo: boolean('hasLocalVideo', overrideProps.hasLocalVideo || false), @@ -46,6 +57,20 @@ story.add('Default', () => { return ; }); +story.add('No Camera', () => { + const props = createProps({ + availableCameras: [], + }); + return ; +}); + +story.add('Local Video', () => { + const props = createProps({ + hasLocalVideo: true, + }); + return ; +}); + story.add('Local Video', () => { const props = createProps({ hasLocalVideo: true, diff --git a/ts/components/CallingLobby.tsx b/ts/components/CallingLobby.tsx index 58e6b1afe8..44943fe70a 100644 --- a/ts/components/CallingLobby.tsx +++ b/ts/components/CallingLobby.tsx @@ -15,6 +15,7 @@ import { CallBackgroundBlur } from './CallBackgroundBlur'; import { LocalizerType } from '../types/Util'; export type PropsType = { + availableCameras: Array; callDetails: CallDetailsType; callState?: CallState; hasLocalAudio: boolean; @@ -31,6 +32,7 @@ export type PropsType = { }; export const CallingLobby = ({ + availableCameras, callDetails, hasLocalAudio, hasLocalVideo, @@ -95,8 +97,11 @@ export const CallingLobby = ({ }; }, [toggleVideo, toggleAudio]); + // eslint-disable-next-line no-nested-ternary const videoButtonType = hasLocalVideo ? CallingButtonType.VIDEO_ON + : availableCameras.length === 0 + ? CallingButtonType.VIDEO_DISABLED : CallingButtonType.VIDEO_OFF; const audioButtonType = hasLocalAudio ? CallingButtonType.AUDIO_ON @@ -126,7 +131,7 @@ export const CallingLobby = ({
- {hasLocalVideo ? ( + {hasLocalVideo && availableCameras.length > 0 ? (