Merge pull request #5710 from SimonBrandner/resizable-call-view

Resizable CallView
pull/21833/head
Travis Ralston 2021-04-07 11:02:46 -06:00 committed by GitHub
commit 6e6a26f86a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 103 additions and 35 deletions

View File

@ -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";

View File

@ -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;
}
}
@ -104,6 +107,7 @@ limitations under the License.
.mx_CallView_video {
width: 100%;
height: 100%;
position: relative;
z-index: 30;
border-radius: 8px;
@ -177,6 +181,7 @@ limitations under the License.
flex-direction: row;
align-items: center;
justify-content: left;
flex-shrink: 0;
}
.mx_CallView_header_callType {

View File

@ -0,0 +1,46 @@
/*
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
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;
}
}
}
}

View File

@ -16,7 +16,7 @@ limitations under the License.
.mx_VideoFeed_remote {
width: 100%;
max-height: 100%;
height: 100%;
background-color: #000;
z-index: 50;
}

View File

@ -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}
/>
);

View File

@ -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;
@ -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")
@ -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}

View File

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

View File

@ -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,
@ -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} />;
}
}