Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Resizable CallView #5710

Merged
merged 15 commits into from
Apr 7, 2021
1 change: 1 addition & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@
@import "./views/voice_messages/_Waveform.scss";
@import "./views/voip/_CallContainer.scss";
@import "./views/voip/_CallView.scss";
@import "./views/voip/_CallViewForRoom.scss";
@import "./views/voip/_DialPad.scss";
@import "./views/voip/_DialPadContextMenu.scss";
@import "./views/voip/_DialPadModal.scss";
Expand Down
7 changes: 6 additions & 1 deletion res/css/views/voip/_CallView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ limitations under the License.
.mx_CallView_large {
padding-bottom: 10px;
margin: 5px 5px 5px 18px;
display: flex;
flex-direction: column;
flex: 1;

.mx_CallView_voice {
height: 360px;
flex: 1;
}
}

Expand Down Expand Up @@ -104,6 +107,7 @@ limitations under the License.

.mx_CallView_video {
width: 100%;
height: 100%;
position: relative;
z-index: 30;
border-radius: 8px;
Expand Down Expand Up @@ -177,6 +181,7 @@ limitations under the License.
flex-direction: row;
align-items: center;
justify-content: left;
flex-shrink: 0;
}

.mx_CallView_header_callType {
Expand Down
46 changes: 46 additions & 0 deletions res/css/views/voip/_CallViewForRoom.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright 2021 Šimon Brandner <[email protected]>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_CallViewForRoom {
overflow: hidden;

.mx_CallViewForRoom_ResizeWrapper {
display: flex;
margin-bottom: 8px;

&:hover .mx_CallViewForRoom_ResizeHandle {
// Need to use important to override element style attributes
// set by re-resizable
width: 100% !important;

display: flex;
justify-content: center;

&::after {
content: '';
margin-top: 3px;

border-radius: 4px;

height: 4px;
width: 100%;
max-width: 64px;

background-color: $primary-fg-color;
}
}
}
}
2 changes: 1 addition & 1 deletion res/css/views/voip/_VideoFeed.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

.mx_VideoFeed_remote {
width: 100%;
max-height: 100%;
height: 100%;
background-color: #000;
z-index: 50;
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/rooms/AuxPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ export default class AuxPanel extends React.Component<IProps, IState> {
const callView = (
<CallViewForRoom
roomId={this.props.room.roomId}
onResize={this.props.onResize}
maxVideoHeight={this.props.maxHeight}
resizeNotifier={this.props.resizeNotifier}
/>
);

Expand Down
21 changes: 2 additions & 19 deletions src/components/views/voip/CallView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ interface IProps {
// Another ongoing call to display information about
secondaryCall?: MatrixCall,

// maxHeight style attribute for the video panel
maxVideoHeight?: number;

// a callback which is called when the content in the callview changes
// in a way that is likely to cause a resize.
onResize?: any;
Expand Down Expand Up @@ -96,9 +93,6 @@ function exitFullscreen() {
const CONTROLS_HIDE_DELAY = 1000;
// 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 HEADER_HEIGHT = 44;
const BOTTOM_PADDING = 10;
const BOTTOM_MARGIN_TOP_BOTTOM = 10; // top margin plus bottom margin
const CONTEXT_MENU_VPADDING = 8; // How far the context menu sits above the button (px)

@replaceableComponent("views.voip.CallView")
Expand Down Expand Up @@ -548,20 +542,9 @@ export default class CallView extends React.Component<IProps, IState> {
localVideoFeed = <VideoFeed type={VideoFeedType.Local} call={this.props.call} />;
}

// if we're fullscreen, we don't want to set a maxHeight on the video element.
const maxVideoHeight = getFullScreenElement() || !this.props.maxVideoHeight ? null : (
this.props.maxVideoHeight - (HEADER_HEIGHT + BOTTOM_PADDING + BOTTOM_MARGIN_TOP_BOTTOM)
);
contentView = <div className={containerClasses}
ref={this.contentRef} onMouseMove={this.onMouseMove}
// Put the max height on here too because this div is ended up 4px larger than the content
// and is causing it to scroll, and I am genuinely baffled as to why.
style={{maxHeight: maxVideoHeight}}
>
contentView = <div className={containerClasses} ref={this.contentRef} onMouseMove={this.onMouseMove}>
{onHoldBackground}
<VideoFeed type={VideoFeedType.Remote} call={this.props.call} onResize={this.props.onResize}
maxHeight={maxVideoHeight}
/>
<VideoFeed type={VideoFeedType.Remote} call={this.props.call} onResize={this.props.onResize} />
{localVideoFeed}
{holdTransferContent}
{callControls}
Expand Down
53 changes: 46 additions & 7 deletions src/components/views/voip/CallViewForRoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import React from 'react';
import CallHandler from '../../../CallHandler';
import CallView from './CallView';
import dis from '../../../dispatcher/dispatcher';
import {Resizable} from "re-resizable";
import ResizeNotifier from "../../../utils/ResizeNotifier";
import {replaceableComponent} from "../../../utils/replaceableComponent";

interface IProps {
Expand All @@ -28,9 +30,7 @@ interface IProps {
// maxHeight style attribute for the video panel
maxVideoHeight?: number;

// a callback which is called when the content in the callview changes
// in a way that is likely to cause a resize.
onResize?: any;
resizeNotifier: ResizeNotifier,
}

interface IState {
Expand Down Expand Up @@ -79,11 +79,50 @@ export default class CallViewForRoom extends React.Component<IProps, IState> {
return call;
}

private onResizeStart = () => {
this.props.resizeNotifier.startResizing();
};

private onResize = () => {
this.props.resizeNotifier.notifyTimelineHeightChanged();
};

private onResizeStop = () => {
this.props.resizeNotifier.stopResizing();
};

public render() {
if (!this.state.call) return null;

return <CallView call={this.state.call} pipMode={false}
onResize={this.props.onResize} maxVideoHeight={this.props.maxVideoHeight}
/>;
// We subtract 8 as it the margin-bottom of the mx_CallViewForRoom_ResizeWrapper
const maxHeight = this.props.maxVideoHeight - 8;

return (
<div className="mx_CallViewForRoom">
<Resizable
minHeight={380}
maxHeight={maxHeight}
enable={{
top: false,
right: false,
bottom: true,
left: false,
topRight: false,
bottomRight: false,
bottomLeft: false,
topLeft: false,
}}
onResizeStart={this.onResizeStart}
onResize={this.onResize}
onResizeStop={this.onResizeStop}
className="mx_CallViewForRoom_ResizeWrapper"
handleClasses={{bottom: "mx_CallViewForRoom_ResizeHandle"}}
>
<CallView
call={this.state.call}
pipMode={false}
/>
</Resizable>
</div>
);
}
}
8 changes: 1 addition & 7 deletions src/components/views/voip/VideoFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ interface IProps {

type: VideoFeedType,

// maxHeight style attribute for the video element
maxHeight?: number,

// a callback which is called when the video element is resized
// due to a change in video metadata
onResize?: (e: Event) => void,
Expand Down Expand Up @@ -82,9 +79,6 @@ export default class VideoFeed extends React.Component<IProps> {
),
};

let videoStyle = {};
if (this.props.maxHeight) videoStyle = { maxHeight: this.props.maxHeight };

return <video className={classnames(videoClasses)} ref={this.vid} style={videoStyle} />;
return <video className={classnames(videoClasses)} ref={this.vid} />;
}
}