diff options
-rw-r--r-- | src/FilesSidebarCallViewApp.vue | 2 | ||||
-rw-r--r-- | src/components/CallView/CallView.vue | 63 | ||||
-rw-r--r-- | src/components/CallView/LocalMediaControls.vue | 10 | ||||
-rw-r--r-- | src/components/CallView/LocalVideo.vue | 15 | ||||
-rw-r--r-- | src/components/CallView/Video.vue | 19 |
5 files changed, 77 insertions, 32 deletions
diff --git a/src/FilesSidebarCallViewApp.vue b/src/FilesSidebarCallViewApp.vue index 65802f3c6..8fdac4ba4 100644 --- a/src/FilesSidebarCallViewApp.vue +++ b/src/FilesSidebarCallViewApp.vue @@ -19,7 +19,7 @@ --> <template> - <CallView v-show="isInCall" :token="token" /> + <CallView v-show="isInCall" :token="token" :use-constrained-layout="true" /> </template> <script> diff --git a/src/components/CallView/CallView.vue b/src/components/CallView/CallView.vue index 867b2b537..411d8c538 100644 --- a/src/components/CallView/CallView.vue +++ b/src/components/CallView/CallView.vue @@ -26,17 +26,20 @@ :key="callParticipantModel.attributes.peerId" :model="callParticipantModel" :shared-data="sharedDatas[callParticipantModel.attributes.peerId]" + :use-constrained-layout="useConstrainedLayout" @switchScreenToId="_switchScreenToId" /> <Video :key="'placeholder' + callParticipantModel.attributes.peerId" :placeholder-for-promoted="true" :model="callParticipantModel" :shared-data="sharedDatas[callParticipantModel.attributes.peerId]" + :use-constrained-layout="useConstrainedLayout" @switchScreenToId="_switchScreenToId" /> </template> <LocalVideo ref="localVideo" :local-media-model="localMediaModel" :local-call-participant-model="localCallParticipantModel" + :use-constrained-layout="useConstrainedLayout" @switchScreenToId="_switchScreenToId" /> </div> <div id="screens"> @@ -68,6 +71,13 @@ export default { Video, }, + props: { + useConstrainedLayout: { + type: Boolean, + default: false, + }, + }, + data() { return { speakers: [], @@ -92,6 +102,7 @@ export default { const callViewClass = { 'incall': this.remoteParticipantsCount > 0, 'screensharing': this.screenSharingActive, + 'constrained-layout': this.useConstrainedLayout, } callViewClass['participants-' + (this.remoteParticipantsCount + 1)] = true @@ -340,6 +351,15 @@ export default { max-height: 200px; } +.constrained-layout.screensharing .videoContainer { + max-height: 100px; + + /* Avatars slightly overflow the container; although they overlap the shared + * screen it is not too bad and it is better than compressing even further + * the shared screen. */ + overflow: visible; +} + ::v-deep video { z-index: 0; max-height: 100%; @@ -376,6 +396,12 @@ export default { box-shadow: 0 0 15px var(--color-box-shadow); } +.constrained-layout #videos .videoContainer:not(.promoted) ::v-deep video { + /* Make the unpromoted videos smaller to not overlap too much the promoted + * video */ + max-height: 100px; +} + #videos .videoContainer ::v-deep .avatardiv { box-shadow: 0 0 15px var(--color-box-shadow); } @@ -397,19 +423,6 @@ export default { background-color: #b9b9b9 !important; } -/* Text avatars need to be forced to 128px, as imageplaceholder() overrides - * the given size with the actual height of the element it was called on, so - * the text avatar may have any hardcoded height. Note that this does not - * apply to regular image avatars, as in that case they are always requested - * with a size of 128px. */ -.videoContainer ::v-deep .avatar-container .avatardiv { - width: 128px !important; - height: 128px !important; - line-height: 128px !important; - /* imageplaceholder() sets font-size to "height * 0.55" */ - font-size: 70.4px !important; -} - .videoContainer ::v-deep .avatar-container .avatardiv { display: block; margin-left: auto; @@ -470,6 +483,12 @@ export default { max-height: 35%; } } +.constrained-layout.participants-1 .videoView, +.constrained-layout.participants-2 .videoView { + /* Do not force the width to 200px, as otherwise the video is too tall and + * overlaps too much with the promoted video. */ + min-width: initial; +} .participants-1 .videoView ::v-deep video, .participants-2 .videoView ::v-deep video { position: absolute; @@ -487,6 +506,12 @@ export default { background-color: transparent; } +.constrained-layout.screensharing #screens { + /* The row with the participants is shorter in the constrained layout to + * make room for the promoted video and the shared screens. */ + height: calc(100% - 100px); +} + .screensharing .screenContainer { position: relative; width: 100%; @@ -509,6 +534,13 @@ export default { text-overflow: ellipsis; } +.constrained-layout ::v-deep .nameIndicator { + /* Reduce padding to bring the name closer to the bottom */ + padding: 3px; + /* Use default font size, as it takes too much space otherwise */ + font-size: initial; +} + ::v-deep .videoView .nameIndicator { padding: 0; overflow: visible; @@ -531,6 +563,11 @@ export default { padding: 12px 35%; } +.constrained-layout.participants-2 ::v-deep .videoContainer.promoted + .videoContainer-dummy .nameIndicator { + /* Reduce padding to bring the name closer to the bottom */ + padding: 3px 35%; +} + #videos .videoContainer.speaking:not(.videoView) ::v-deep .nameIndicator, #videos .videoContainer.videoView.speaking ::v-deep .nameIndicator .icon-audio { animation: pulse 1s; diff --git a/src/components/CallView/LocalMediaControls.vue b/src/components/CallView/LocalMediaControls.vue index 580873067..3876507fe 100644 --- a/src/components/CallView/LocalMediaControls.vue +++ b/src/components/CallView/LocalMediaControls.vue @@ -98,13 +98,16 @@ export default { type: Object, required: true, }, + screenSharingButtonHidden: { + type: Boolean, + default: false, + }, }, data() { return { mounted: false, speakingWhileMutedNotification: null, - screenSharingButtonHidden: false, screenSharingMenuOpen: false, splitScreenSharingMenu: false, } @@ -341,11 +344,6 @@ export default { } }) }, - - hideScreenSharingButton() { - this.screenSharingButtonHidden = true - }, - }, } </script> diff --git a/src/components/CallView/LocalVideo.vue b/src/components/CallView/LocalVideo.vue index 24751df81..26d9e5b64 100644 --- a/src/components/CallView/LocalVideo.vue +++ b/src/components/CallView/LocalVideo.vue @@ -37,6 +37,7 @@ <LocalMediaControls ref="localMediaControls" :model="localMediaModel" :local-call-participant-model="localCallParticipantModel" + :screen-sharing-button-hidden="useConstrainedLayout" @switchScreenToId="$emit('switchScreenToId', $event)" /> </div> </template> @@ -64,12 +65,10 @@ export default { type: Object, required: true, }, - }, - - data() { - return { - avatarSize: 128, - } + useConstrainedLayout: { + type: Boolean, + default: false, + }, }, computed: { @@ -86,6 +85,10 @@ export default { return this.localCallParticipantModel.attributes.guestName || localStorage.getItem('nick') || '?' }, + avatarSize() { + return this.useConstrainedLayout ? 64 : 128 + }, + }, watch: { diff --git a/src/components/CallView/Video.vue b/src/components/CallView/Video.vue index 81719bc1e..b6caefdab 100644 --- a/src/components/CallView/Video.vue +++ b/src/components/CallView/Video.vue @@ -97,12 +97,10 @@ export default { type: Object, required: true, }, - }, - - data() { - return { - avatarSize: 128, - } + useConstrainedLayout: { + type: Boolean, + default: false, + }, }, computed: { @@ -116,6 +114,10 @@ export default { } }, + avatarSize() { + return (this.useConstrainedLayout && !this.sharedData.promoted) ? 64 : 128 + }, + avatarClass() { return { 'icon-loading': this.model.attributes.connectionState !== ConnectionState.CONNECTED && this.model.attributes.connectionState !== ConnectionState.COMPLETED && this.model.attributes.connectionState !== ConnectionState.FAILED_NO_RESTART, @@ -248,6 +250,11 @@ export default { text-align: center; } +.constrained-layout .mediaIndicator { + /* Move the media indicator closer to the bottom */ + bottom: 16px; +} + .muteIndicator, .hideRemoteVideo, .screensharingIndicator, |