Fix webcam size after minimize the presentation #7570
This commit is contained in:
parent
7b59f1d309
commit
0c81eda94e
@ -425,7 +425,20 @@ export default class WebcamDraggableOverlay extends Component {
|
||||
hideOverlay,
|
||||
disableVideo,
|
||||
audioModalIsOpen,
|
||||
refMediaContainer,
|
||||
} = this.props;
|
||||
const { current: mediaContainer } = refMediaContainer;
|
||||
|
||||
let mediaContainerRect;
|
||||
let mediaHeight;
|
||||
if (mediaContainer) {
|
||||
mediaContainerRect = mediaContainer.getBoundingClientRect();
|
||||
const {
|
||||
height,
|
||||
} = mediaContainerRect;
|
||||
mediaHeight = height;
|
||||
}
|
||||
|
||||
|
||||
const {
|
||||
dragging,
|
||||
@ -441,6 +454,14 @@ export default class WebcamDraggableOverlay extends Component {
|
||||
isMinWidth,
|
||||
} = this.state;
|
||||
|
||||
|
||||
console.log(
|
||||
'%c swapLayout %s',
|
||||
'background:black;color:#fff;',
|
||||
swapLayout,
|
||||
);
|
||||
|
||||
|
||||
const webcamBySelectorCount = WebcamDraggableOverlay.getWebcamBySelectorCount();
|
||||
|
||||
const contentClassName = cx({
|
||||
@ -523,6 +544,8 @@ export default class WebcamDraggableOverlay extends Component {
|
||||
? (
|
||||
<VideoProviderContainer
|
||||
cursor={cursor()}
|
||||
swapLayout={swapLayout}
|
||||
mediaHeight={mediaHeight}
|
||||
onMount={this.videoMounted}
|
||||
onUpdate={this.videoUpdated}
|
||||
/>
|
||||
|
@ -190,9 +190,13 @@ class VideoProvider extends Component {
|
||||
&& peer.peerConnection.getRemoteStreams().length > 0;
|
||||
|
||||
if (hasLocalStream) {
|
||||
this.customGetStats(peer.peerConnection, peer.peerConnection.getLocalStreams()[0].getVideoTracks()[0], (stats => updateWebcamStats(id, stats)), true);
|
||||
this.customGetStats(peer.peerConnection,
|
||||
peer.peerConnection.getLocalStreams()[0].getVideoTracks()[0],
|
||||
(stats => updateWebcamStats(id, stats)), true);
|
||||
} else if (hasRemoteStream) {
|
||||
this.customGetStats(peer.peerConnection, peer.peerConnection.getRemoteStreams()[0].getVideoTracks()[0], (stats => updateWebcamStats(id, stats)), true);
|
||||
this.customGetStats(peer.peerConnection,
|
||||
peer.peerConnection.getRemoteStreams()[0].getVideoTracks()[0],
|
||||
(stats => updateWebcamStats(id, stats)), true);
|
||||
}
|
||||
});
|
||||
}, 5000);
|
||||
@ -833,9 +837,9 @@ class VideoProvider extends Component {
|
||||
|
||||
let videoBitrate;
|
||||
if (videoStats.packetsReceived > 0) { // Remote video
|
||||
videoLostPercentage = ((videoStats
|
||||
.packetsLost / ((videoStats
|
||||
.packetsLost + videoStats.packetsReceived) * 100)) || 0).toFixed(1);
|
||||
videoLostPercentage = ((videoStats.packetsLost / (
|
||||
(videoStats.packetsLost + videoStats.packetsReceived) * 100
|
||||
)) || 0).toFixed(1);
|
||||
videoBitrate = Math.floor(videoKbitsReceivedPerSecond || 0);
|
||||
videoLostRecentPercentage = ((videoIntervalPacketsLost / ((videoIntervalPacketsLost
|
||||
+ videoIntervalPacketsReceived) * 100)) || 0).toFixed(1);
|
||||
@ -1005,10 +1009,18 @@ class VideoProvider extends Component {
|
||||
const { socketOpen } = this.state;
|
||||
if (!socketOpen) return null;
|
||||
|
||||
const { users, enableVideoStats, cursor } = this.props;
|
||||
const {
|
||||
users,
|
||||
enableVideoStats,
|
||||
cursor,
|
||||
swapLayout,
|
||||
mediaHeight,
|
||||
} = this.props;
|
||||
return (
|
||||
<VideoList
|
||||
cursor={cursor}
|
||||
swapLayout={swapLayout}
|
||||
mediaHeight={mediaHeight}
|
||||
users={users}
|
||||
onMount={this.createVideoTag}
|
||||
getStats={this.getStats}
|
||||
|
@ -11,6 +11,8 @@ const VideoProviderContainer = ({ children, ...props }) => {
|
||||
|
||||
export default withTracker(props => ({
|
||||
cursor: props.cursor,
|
||||
swapLayout: props.swapLayout,
|
||||
mediaHeight: props.mediaHeight,
|
||||
meetingId: VideoService.meetingId(),
|
||||
users: VideoService.getAllUsersVideo(),
|
||||
userId: VideoService.userId(),
|
||||
|
@ -52,7 +52,15 @@ class VideoList extends Component {
|
||||
|
||||
renderVideoList() {
|
||||
const {
|
||||
intl, users, onMount, getStats, stopGettingStats, enableVideoStats, cursor,
|
||||
intl,
|
||||
users,
|
||||
onMount,
|
||||
getStats,
|
||||
stopGettingStats,
|
||||
enableVideoStats,
|
||||
cursor,
|
||||
swapLayout,
|
||||
mediaHeight,
|
||||
} = this.props;
|
||||
const { focusedId } = this.state;
|
||||
|
||||
@ -73,7 +81,8 @@ class VideoList extends Component {
|
||||
<div
|
||||
key={user.id}
|
||||
className={cx({
|
||||
[styles.videoListItem]: true,
|
||||
[styles.videoListItem]: !swapLayout,
|
||||
[styles.videoListItemSwapLayout]: swapLayout,
|
||||
[styles.focused]: focusedId === user.id && users.length > 2,
|
||||
})}
|
||||
style={{
|
||||
@ -88,6 +97,8 @@ class VideoList extends Component {
|
||||
getStats={(videoRef, callback) => getStats(user.id, videoRef, callback)}
|
||||
stopGettingStats={() => stopGettingStats(user.id)}
|
||||
enableVideoStats={enableVideoStats}
|
||||
swapLayout={swapLayout}
|
||||
mediaHeight={mediaHeight}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -100,6 +111,8 @@ class VideoList extends Component {
|
||||
<div
|
||||
ref={(ref) => { this.canvas = ref; }}
|
||||
className={styles.videoCanvas}
|
||||
|
||||
// TODO adicionar videoCanvasSwapLayout quando for swaplayout
|
||||
>
|
||||
{!users.length ? null : (
|
||||
<div
|
||||
|
@ -11,13 +11,29 @@
|
||||
--audio-indicator-fs: 75%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.videoCanvasSwapLayout {
|
||||
--cam-dropdown-width: 70%;
|
||||
--audio-indicator-width: 1.12rem;
|
||||
--audio-indicator-fs: 75%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.videoList {
|
||||
@ -41,6 +57,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.videoListSwapLayout {
|
||||
display: grid;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||
grid-template-columns: repeat(auto-fit, minmax(var(--video-width), 1fr));
|
||||
grid-auto-columns: minmax(var(--video-width), 1fr);
|
||||
grid-auto-rows: 1fr;
|
||||
grid-gap: 5px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
grid-auto-flow: column dense;
|
||||
|
||||
@include mq($medium-up) {
|
||||
grid-gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.videoListItem {
|
||||
display: flex;
|
||||
max-width: fit-content;
|
||||
@ -62,6 +96,25 @@
|
||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||
}
|
||||
|
||||
.videoListItemSwapLayout {
|
||||
display: flex;
|
||||
max-width: -moz-fit-content;
|
||||
max-height: -moz-fit-content;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&.focused {
|
||||
grid-column: 1 / span 2;
|
||||
grid-row: 1 / span 2;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
min-width: 100%;
|
||||
@ -107,6 +160,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
.contentSwapLayout {
|
||||
position: relative;
|
||||
min-width: 100%;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
border-radius: 5px;
|
||||
|
||||
background-color: var(--color-gray);
|
||||
|
||||
width: 100%;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border: 5px solid var(--color-white-with-transparency);
|
||||
border-radius: 5px;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
:global(.animationsEnabled) & {
|
||||
transition: opacity .1s;
|
||||
}
|
||||
}
|
||||
|
||||
&.talking::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.focused & {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.contentLoading {
|
||||
width: var(--video-width);
|
||||
min-width: var(--video-width);
|
||||
@ -114,8 +209,12 @@
|
||||
min-height: calc(var(--video-width) / var(--video-ratio));
|
||||
}
|
||||
|
||||
%media-area {
|
||||
.contentLoadingSwapLayout {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
%media-area {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
@ -129,7 +129,9 @@ class VideoListItem extends Component {
|
||||
|
||||
render() {
|
||||
const { showStats, stats, videoIsReady } = this.state;
|
||||
const { user, numOfUsers } = this.props;
|
||||
const {
|
||||
user, numOfUsers, swapLayout, mediaHeight,
|
||||
} = this.props;
|
||||
const availableActions = this.getAvailableActions();
|
||||
const enableVideoMenu = Meteor.settings.public.kurento.enableVideoMenu || false;
|
||||
|
||||
@ -138,13 +140,18 @@ class VideoListItem extends Component {
|
||||
|
||||
return (
|
||||
<div className={cx({
|
||||
[styles.content]: true,
|
||||
[styles.content]: !swapLayout,
|
||||
[styles.contentSwapLayout]: swapLayout,
|
||||
[styles.talking]: user.isTalking,
|
||||
[styles.contentLoading]: !videoIsReady,
|
||||
[styles.contentLoading]: !videoIsReady && !swapLayout,
|
||||
[styles.contentLoadingSwapLayout]: !videoIsReady && swapLayout,
|
||||
})}
|
||||
>
|
||||
{!videoIsReady && <div className={styles.connecting} />}
|
||||
<video
|
||||
style={{
|
||||
maxHeight: mediaHeight,
|
||||
}}
|
||||
muted
|
||||
className={cx({
|
||||
[styles.media]: true,
|
||||
|
Loading…
Reference in New Issue
Block a user