From 3741e96c617b2c73a7c4d02bb3d88bda00b33dd2 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 5 Nov 2021 14:42:46 +1100 Subject: [PATCH] show input toggles in fullscreen mode too --- ts/components/session/calling/CallButtons.tsx | 288 ++++++++++++++++++ .../calling/CallInFullScreenContainer.tsx | 25 +- .../calling/InConversationCallContainer.tsx | 229 +------------- 3 files changed, 320 insertions(+), 222 deletions(-) create mode 100644 ts/components/session/calling/CallButtons.tsx diff --git a/ts/components/session/calling/CallButtons.tsx b/ts/components/session/calling/CallButtons.tsx new file mode 100644 index 000000000..809691a58 --- /dev/null +++ b/ts/components/session/calling/CallButtons.tsx @@ -0,0 +1,288 @@ +import { SessionIconButton } from '../icon'; +import { animation, contextMenu, Item, Menu } from 'react-contexify'; +import { InputItem } from '../../../session/utils/CallManager'; +import { setFullScreenCall } from '../../../state/ducks/conversations'; +import { CallManager, ToastUtils } from '../../../session/utils'; +import React from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { getHasOngoingCallWithPubkey } from '../../../state/selectors/conversations'; +import { DropDownAndToggleButton } from '../icon/DropDownAndToggleButton'; +import styled from 'styled-components'; + +const videoTriggerId = 'video-menu-trigger-id'; +const audioTriggerId = 'audio-menu-trigger-id'; + +export const VideoInputButton = ({ + currentConnectedCameras, + localStreamVideoIsMuted, + hideArrowIcon = false, +}: { + currentConnectedCameras: Array; + localStreamVideoIsMuted: boolean; + hideArrowIcon?: boolean; +}) => { + return ( + <> + { + void handleCameraToggle(currentConnectedCameras, localStreamVideoIsMuted); + }} + onArrowClick={e => { + showVideoInputMenu(currentConnectedCameras, e); + }} + hidePopoverArrow={hideArrowIcon} + /> + + + + ); +}; + +export const AudioInputButton = ({ + currentConnectedAudioInputs, + isAudioMuted, + hideArrowIcon = false, +}: { + currentConnectedAudioInputs: Array; + isAudioMuted: boolean; + hideArrowIcon?: boolean; +}) => { + return ( + <> + { + void handleMicrophoneToggle(currentConnectedAudioInputs, isAudioMuted); + }} + onArrowClick={e => { + showAudioInputMenu(currentConnectedAudioInputs, e); + }} + hidePopoverArrow={hideArrowIcon} + /> + + + + ); +}; + +const VideoInputMenu = ({ + triggerId, + camerasList, +}: { + triggerId: string; + camerasList: Array; +}) => { + return ( + + {camerasList.map(m => { + return ( + { + void CallManager.selectCameraByDeviceId(m.deviceId); + }} + > + {m.label.substr(0, 40)} + + ); + })} + + ); +}; + +const AudioInputMenu = ({ + triggerId, + audioInputsList, +}: { + triggerId: string; + audioInputsList: Array; +}) => { + return ( + + {audioInputsList.map(m => { + return ( + { + void CallManager.selectAudioInputByDeviceId(m.deviceId); + }} + > + {m.label.substr(0, 40)} + + ); + })} + + ); +}; + +export const ShowInFullScreenButton = ({ isFullScreen }: { isFullScreen: boolean }) => { + const dispatch = useDispatch(); + + const showInFullScreen = () => { + if (isFullScreen) { + dispatch(setFullScreenCall(false)); + } else { + dispatch(setFullScreenCall(true)); + } + }; + + return ( + + ); +}; + +export const HangUpButton = () => { + const ongoingCallPubkey = useSelector(getHasOngoingCallWithPubkey); + + const handleEndCall = async () => { + // call method to end call connection + if (ongoingCallPubkey) { + await CallManager.USER_hangup(ongoingCallPubkey); + } + }; + + return ( + + ); +}; + +const showAudioInputMenu = ( + currentConnectedAudioInputs: Array, + e: React.MouseEvent +) => { + if (currentConnectedAudioInputs.length === 0) { + ToastUtils.pushNoAudioInputFound(); + return; + } + contextMenu.show({ + id: audioTriggerId, + event: e, + }); +}; + +const showVideoInputMenu = ( + currentConnectedCameras: Array, + e: React.MouseEvent +) => { + if (currentConnectedCameras.length === 0) { + ToastUtils.pushNoCameraFound(); + return; + } + contextMenu.show({ + id: videoTriggerId, + event: e, + }); +}; + +const handleCameraToggle = async ( + currentConnectedCameras: Array, + localStreamVideoIsMuted: boolean +) => { + if (!currentConnectedCameras.length) { + ToastUtils.pushNoCameraFound(); + + return; + } + if (localStreamVideoIsMuted) { + // select the first one + await CallManager.selectCameraByDeviceId(currentConnectedCameras[0].deviceId); + } else { + await CallManager.selectCameraByDeviceId(CallManager.INPUT_DISABLED_DEVICE_ID); + } +}; + +const handleMicrophoneToggle = async ( + currentConnectedAudioInputs: Array, + isAudioMuted: boolean +) => { + if (!currentConnectedAudioInputs.length) { + ToastUtils.pushNoAudioInputFound(); + + return; + } + if (isAudioMuted) { + // selects the first one + await CallManager.selectAudioInputByDeviceId(currentConnectedAudioInputs[0].deviceId); + } else { + await CallManager.selectAudioInputByDeviceId(CallManager.INPUT_DISABLED_DEVICE_ID); + } +}; + +const StyledCallWindowControls = styled.div` + position: absolute; + + bottom: 0px; + width: 100%; + height: 100%; + align-items: flex-end; + padding: 10px; + border-radius: 10px; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + transition: all 0.25s ease-in-out; + + display: flex; + + justify-content: center; + opacity: 0; + &:hover { + opacity: 1; + } +`; + +export const CallWindowControls = ({ + currentConnectedCameras, + currentConnectedAudioInputs, + isAudioMuted, + remoteStreamVideoIsMuted, + localStreamVideoIsMuted, + isFullScreen, +}: { + isAudioMuted: boolean; + localStreamVideoIsMuted: boolean; + remoteStreamVideoIsMuted: boolean; + currentConnectedAudioInputs: Array; + currentConnectedCameras: Array; + isFullScreen: boolean; +}) => { + return ( + + + + + + {!remoteStreamVideoIsMuted && } + + ); +}; diff --git a/ts/components/session/calling/CallInFullScreenContainer.tsx b/ts/components/session/calling/CallInFullScreenContainer.tsx index 2ad6acf77..13fc55008 100644 --- a/ts/components/session/calling/CallInFullScreenContainer.tsx +++ b/ts/components/session/calling/CallInFullScreenContainer.tsx @@ -9,6 +9,7 @@ import { getCallIsInFullScreen, getHasOngoingCallWithFocusedConvo, } from '../../../state/selectors/conversations'; +import { CallWindowControls } from './CallButtons'; import { StyledVideoElement } from './DraggableCallContainer'; const CallInFullScreenVisible = styled.div` @@ -30,10 +31,14 @@ export const CallInFullScreenContainer = () => { const ongoingCallWithFocused = useSelector(getHasOngoingCallWithFocusedConvo); const hasOngoingCallFullScreen = useSelector(getCallIsInFullScreen); - const { remoteStream, remoteStreamVideoIsMuted } = useVideoCallEventsListener( - 'CallInFullScreenContainer', - true - ); + const { + remoteStream, + remoteStreamVideoIsMuted, + currentConnectedAudioInputs, + currentConnectedCameras, + isAudioMuted, + localStreamVideoIsMuted, + } = useVideoCallEventsListener('CallInFullScreenContainer', true); const videoRefRemote = React.useRef(null); @@ -57,7 +62,9 @@ export const CallInFullScreenContainer = () => { } if (videoRefRemote?.current) { - videoRefRemote.current.srcObject = remoteStream; + if (videoRefRemote.current.srcObject !== remoteStream) { + videoRefRemote.current.srcObject = remoteStream; + } } return ( @@ -67,6 +74,14 @@ export const CallInFullScreenContainer = () => { autoPlay={true} isVideoMuted={remoteStreamVideoIsMuted} /> + ); }; diff --git a/ts/components/session/calling/InConversationCallContainer.tsx b/ts/components/session/calling/InConversationCallContainer.tsx index 667bdde48..dc1f43620 100644 --- a/ts/components/session/calling/InConversationCallContainer.tsx +++ b/ts/components/session/calling/InConversationCallContainer.tsx @@ -1,9 +1,9 @@ import React, { useRef } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import styled from 'styled-components'; import _ from 'underscore'; -import { CallManager, ToastUtils, UserUtils } from '../../../session/utils'; +import { UserUtils } from '../../../session/utils'; import { getHasOngoingCallWith, getHasOngoingCallWithFocusedConvo, @@ -11,13 +11,9 @@ import { getHasOngoingCallWithFocusedConvosIsConnecting, getHasOngoingCallWithPubkey, } from '../../../state/selectors/conversations'; -import { SessionIconButton } from '../icon'; -import { animation, contextMenu, Item, Menu } from 'react-contexify'; -import { InputItem } from '../../../session/utils/CallManager'; -import { DropDownAndToggleButton } from '../icon/DropDownAndToggleButton'; import { StyledVideoElement } from './DraggableCallContainer'; import { Avatar, AvatarSize } from '../../Avatar'; -import { setFullScreenCall } from '../../../state/ducks/conversations'; + import { useVideoCallEventsListener } from '../../../hooks/useVideoEventListener'; import { useAvatarPath, @@ -25,6 +21,7 @@ import { useOurConversationUsername, } from '../../../hooks/useParamSelector'; import { useModuloWithTripleDots } from '../../../hooks/useModuloWithTripleDots'; +import { CallWindowControls } from './CallButtons'; const VideoContainer = styled.div` height: 100%; @@ -43,30 +40,6 @@ const InConvoCallWindow = styled.div` flex-grow: 1; `; -const InConvoCallWindowControls = styled.div` - position: absolute; - - bottom: 0px; - width: 100%; - height: 100%; - align-items: flex-end; - padding: 10px; - border-radius: 10px; - margin-left: auto; - margin-right: auto; - left: 0; - right: 0; - transition: all 0.25s ease-in-out; - - display: flex; - - justify-content: center; - opacity: 0; - &:hover { - opacity: 1; - } -`; - const RelativeCallWindow = styled.div` position: relative; height: 100%; @@ -74,56 +47,6 @@ const RelativeCallWindow = styled.div` flex-grow: 1; `; -const VideoInputMenu = ({ - triggerId, - camerasList, -}: { - triggerId: string; - camerasList: Array; -}) => { - return ( - - {camerasList.map(m => { - return ( - { - void CallManager.selectCameraByDeviceId(m.deviceId); - }} - > - {m.label.substr(0, 40)} - - ); - })} - - ); -}; - -const AudioInputMenu = ({ - triggerId, - audioInputsList, -}: { - triggerId: string; - audioInputsList: Array; -}) => { - return ( - - {audioInputsList.map(m => { - return ( - { - void CallManager.selectAudioInputByDeviceId(m.deviceId); - }} - > - {m.label.substr(0, 40)} - - ); - })} - - ); -}; - const CenteredAvatarInConversation = styled.div` top: -50%; transform: translateY(-50%); @@ -137,116 +60,6 @@ const CenteredAvatarInConversation = styled.div` align-items: center; `; -const videoTriggerId = 'video-menu-trigger-id'; -const audioTriggerId = 'audio-menu-trigger-id'; - -const ShowInFullScreenButton = () => { - const dispatch = useDispatch(); - - const showInFullScreen = () => { - dispatch(setFullScreenCall(true)); - }; - - return ( - - ); -}; - -const HangUpButton = () => { - const ongoingCallPubkey = useSelector(getHasOngoingCallWithPubkey); - - const handleEndCall = async () => { - // call method to end call connection - if (ongoingCallPubkey) { - await CallManager.USER_hangup(ongoingCallPubkey); - } - }; - - return ( - - ); -}; - -const showAudioInputMenu = ( - currentConnectedAudioInputs: Array, - e: React.MouseEvent -) => { - if (currentConnectedAudioInputs.length === 0) { - ToastUtils.pushNoAudioInputFound(); - return; - } - contextMenu.show({ - id: audioTriggerId, - event: e, - }); -}; - -const showVideoInputMenu = ( - currentConnectedCameras: Array, - e: React.MouseEvent -) => { - if (currentConnectedCameras.length === 0) { - ToastUtils.pushNoCameraFound(); - return; - } - contextMenu.show({ - id: videoTriggerId, - event: e, - }); -}; - -const handleCameraToggle = async ( - currentConnectedCameras: Array, - localStreamVideoIsMuted: boolean -) => { - if (!currentConnectedCameras.length) { - ToastUtils.pushNoCameraFound(); - - return; - } - if (localStreamVideoIsMuted) { - // select the first one - await CallManager.selectCameraByDeviceId(currentConnectedCameras[0].deviceId); - } else { - await CallManager.selectCameraByDeviceId(CallManager.INPUT_DISABLED_DEVICE_ID); - } -}; - -const handleMicrophoneToggle = async ( - currentConnectedAudioInputs: Array, - isAudioMuted: boolean -) => { - if (!currentConnectedAudioInputs.length) { - ToastUtils.pushNoAudioInputFound(); - - return; - } - if (isAudioMuted) { - // selects the first one - await CallManager.selectAudioInputByDeviceId(currentConnectedAudioInputs[0].deviceId); - } else { - await CallManager.selectAudioInputByDeviceId(CallManager.INPUT_DISABLED_DEVICE_ID); - } -}; - const StyledCenteredLabel = styled.div` position: absolute; left: 50%; @@ -362,32 +175,14 @@ export const InConversationCallContainer = () => { )} - - - { - void handleCameraToggle(currentConnectedCameras, localStreamVideoIsMuted); - }} - onArrowClick={e => { - showVideoInputMenu(currentConnectedCameras, e); - }} - /> - { - void handleMicrophoneToggle(currentConnectedAudioInputs, isAudioMuted); - }} - onArrowClick={e => { - showAudioInputMenu(currentConnectedAudioInputs, e); - }} - /> - {!remoteStreamVideoIsMuted && } - - - + );