diff --git a/res/css/views/voip/_CallView.scss b/res/css/views/voip/_CallView.scss index 59298ef8e62..104e2993d80 100644 --- a/res/css/views/voip/_CallView.scss +++ b/res/css/views/voip/_CallView.scss @@ -279,7 +279,7 @@ limitations under the License. max-width: 240px; } -.mx_CallView_header_phoneIcon { +.mx_CallView_header_callTypeIcon { display: inline-block; margin-right: 6px; height: 16px; @@ -293,12 +293,19 @@ limitations under the License. height: 16px; width: 16px; - background-color: $warning-color; + background-color: $secondary-fg-color; mask-repeat: no-repeat; mask-size: contain; mask-position: center; + } + + &.mx_CallView_header_callTypeIcon_voice::before { mask-image: url('$(res)/img/element-icons/call/voice-call.svg'); } + + &.mx_CallView_header_callTypeIcon_video::before { + mask-image: url('$(res)/img/element-icons/call/video-call.svg'); + } } .mx_CallView_callControls { @@ -306,7 +313,6 @@ limitations under the License. display: flex; justify-content: center; bottom: 5px; - width: 100%; opacity: 1; transition: opacity 0.5s; z-index: 200; // To be above _all_ feeds diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx index a98c42526ef..481d7b303cb 100644 --- a/src/components/views/voip/CallView.tsx +++ b/src/components/views/voip/CallView.tsx @@ -67,6 +67,7 @@ interface IState { screensharing: boolean; callState: CallState; controlsVisible: boolean; + hoveringControls: boolean; showMoreMenu: boolean; showDialpad: boolean; primaryFeed: CallFeed; @@ -102,7 +103,7 @@ function exitFullscreen() { if (exitMethod) exitMethod.call(document); } -const CONTROLS_HIDE_DELAY = 1000; +const CONTROLS_HIDE_DELAY = 2000; // Height of the header duplicated from CSS because we need to subtract it from our max // height to get the max height of the video const CONTEXT_MENU_VPADDING = 8; // How far the context menu sits above the button (px) @@ -128,6 +129,7 @@ export default class CallView extends React.Component { screensharing: this.props.call.isScreensharing(), callState: this.props.call.state, controlsVisible: true, + hoveringControls: false, showMoreMenu: false, showDialpad: false, primaryFeed: primary, @@ -244,6 +246,7 @@ export default class CallView extends React.Component { }; private onControlsHideTimer = () => { + if (this.state.hoveringControls || this.state.showDialpad || this.state.showMoreMenu) return; this.controlsHideTimer = null; this.setState({ controlsVisible: false, @@ -293,24 +296,10 @@ export default class CallView extends React.Component { private onDialpadClick = (): void => { if (!this.state.showDialpad) { - if (this.controlsHideTimer) { - clearTimeout(this.controlsHideTimer); - this.controlsHideTimer = null; - } - - this.setState({ - showDialpad: true, - controlsVisible: true, - }); + this.setState({ showDialpad: true }); + this.showControls(); } else { - if (this.controlsHideTimer !== null) { - clearTimeout(this.controlsHideTimer); - } - this.controlsHideTimer = window.setTimeout(this.onControlsHideTimer, CONTROLS_HIDE_DELAY); - - this.setState({ - showDialpad: false, - }); + this.setState({ showDialpad: false }); } }; @@ -345,29 +334,16 @@ export default class CallView extends React.Component { }; private onMoreClick = (): void => { - if (this.controlsHideTimer) { - clearTimeout(this.controlsHideTimer); - this.controlsHideTimer = null; - } - - this.setState({ - showMoreMenu: true, - controlsVisible: true, - }); + this.setState({ showMoreMenu: true }); + this.showControls(); }; private closeDialpad = (): void => { - this.setState({ - showDialpad: false, - }); - this.controlsHideTimer = window.setTimeout(this.onControlsHideTimer, CONTROLS_HIDE_DELAY); + this.setState({ showDialpad: false }); }; private closeContextMenu = (): void => { - this.setState({ - showMoreMenu: false, - }); - this.controlsHideTimer = window.setTimeout(this.onControlsHideTimer, CONTROLS_HIDE_DELAY); + this.setState({ showMoreMenu: false }); }; // we register global shortcuts here, they *must not conflict* with local shortcuts elsewhere or both will fire @@ -403,6 +379,15 @@ export default class CallView extends React.Component { } }; + private onCallControlsMouseEnter = (): void => { + this.setState({ hoveringControls: true }); + this.showControls(); + }; + + private onCallControlsMouseLeave = (): void => { + this.setState({ hoveringControls: false }); + }; + private onRoomAvatarClick = (): void => { const userFacingRoomId = CallHandler.sharedInstance().roomIdForCall(this.props.call); dis.dispatch({ @@ -537,8 +522,6 @@ export default class CallView extends React.Component { } // The dial pad & 'more' button actions are only relevant in a connected call - // When not connected, we have to put something there to make the flexbox alignment correct - let dialpadButton; let contextMenuButton; if (this.state.callState === CallState.Connected) { contextMenuButton = ( @@ -549,6 +532,9 @@ export default class CallView extends React.Component { isExpanded={this.state.showMoreMenu} /> ); + } + let dialpadButton; + if (this.state.callState === CallState.Connected && this.props.call.opponentSupportsDTMF()) { dialpadButton = ( { } return ( -
+
{ dialpadButton } { { expandButton }
; + const callTypeIconClassName = classNames("mx_CallView_header_callTypeIcon", { + "mx_CallView_header_callTypeIcon_voice": !isVideoCall, + "mx_CallView_header_callTypeIcon_video": isVideoCall, + }); + let header: React.ReactNode; if (!this.props.pipMode) { header =
-
+
{ callTypeText } { headerControls }
;