Skip to content

Commit

Permalink
Merge pull request #12913 from nextcloud/fix/12910/call-view-style
Browse files Browse the repository at this point in the history
Refactor: clean call view styles and use CSS variables.
  • Loading branch information
DorraJaouad authored Aug 14, 2024
2 parents 242a70b + 99ff068 commit e8b57dd
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 169 deletions.
15 changes: 15 additions & 0 deletions src/components/AvatarWrapper/AvatarWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
:aria-label="t('spreed', 'Federated user')">
<WebIcon :size="14" />
</span>
<NcLoadingIcon v-if="loading"
:size="size"
class="loading" />
</div>
</template>

Expand All @@ -47,6 +50,7 @@ import WebIcon from 'vue-material-design-icons/Web.vue'
import { t } from '@nextcloud/l10n'

import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'

import { ATTENDEE, AVATAR } from '../../constants.js'
import { getUserProxyAvatarOcsUrl } from '../../services/avatarService.ts'
Expand All @@ -59,6 +63,7 @@ export default {
components: {
NcAvatar,
WebIcon,
NcLoadingIcon,
},

props: {
Expand Down Expand Up @@ -122,6 +127,11 @@ export default {
type: String,
default: undefined,
},

loading: {
type: Boolean,
default: false,
},
},
computed: {
// Determines which icon is displayed
Expand Down Expand Up @@ -279,4 +289,9 @@ export default {
}
}

.loading {
position: absolute;
top: 0;
}

</style>
115 changes: 7 additions & 108 deletions src/components/CallView/CallView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -720,37 +720,26 @@ export default {
<style lang="scss" scoped>
@import '../../assets/variables';

.call-view {
width: 100%;
height: 100%;
overflow: hidden;
background-color: $color-call-background;
}

#call-container {
width: 100%;
height: 100%;
background-color: $color-call-background;
backdrop-filter: var(--filter-background-blur);
--grid-gap: calc(var(--default-grid-baseline) * 2);
}

#videos {
position: absolute;
width: 100%;
height: calc(100% - 50px);
top: 50px;
height: calc(100% - 51px);
top: 51px; // TopBar height
overflow: hidden;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-around;
justify-content: space-around;
-webkit-align-items: flex-end;
align-items: flex-end;
flex-direction: column;
padding: 0 8px 8px 8px;
padding: calc(var(--default-grid-baseline) * 2);
padding-block-start: 0;
}

.video__promoted {
Expand Down Expand Up @@ -793,102 +782,12 @@ export default {
vertical-align: top; /* fix white line below video */
}

#videos .videoContainer :deep(.avatardiv) {
#videos :deep(.avatardiv) {
box-shadow: 0 0 15px var(--color-box-shadow);
}

.participants-1 #videos .videoContainer :deep(video),
.participants-2 #videos .videoContainer :deep(video) {
#videos :deep(video) {
padding: 0;
}

.videoContainer :deep(.avatar-container .avatardiv) {
display: block;
margin-left: auto;
margin-right: auto;
}

.videoContainer.promoted :deep(.avatar-container) {
top: 30%;
}

.videoContainer.promoted :deep(.avatar-container + .nameIndicator) {
display: none;
}

.videoContainer.promoted :deep(.mediaIndicator) {
display: none !important;
}

@media only screen and (max-width: 768px) {
.participants-1 .videoView,
.participants-2 .videoView {
max-height: 35%;
}
}

.participants-1 .videoView :deep(video),
.participants-2 .videoView :deep(video) {
position: absolute;
max-height: 100% !important;
bottom: 0;
border-top-right-radius: 3px;
right: 0;
}

:deep(.nameIndicator) {
position: absolute;
bottom: 0;
left: 0;
padding: 12px;
color: #fff;
text-shadow: 3px 3px 10px rgba(0, 0, 0, .5), 3px -3px 10px rgba(0, 0, 0, .5), -3px 3px 10px rgba(0, 0, 0, .5), -3px -3px 10px rgba(0, 0, 0, .5);
width: 100%;
text-align: center;
font-size: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

:deep(.videoView .nameIndicator) {
padding: 0;
overflow: visible;
}

.participants-1 .videoView :deep(.nameIndicator),
.participants-2 .videoView :deep(.nameIndicator) {
left: initial;
right: 0;
}

.participants-1 .videoView :deep(.avatar-container),
.participants-2 .videoView :deep(.avatar-container) {
left: initial;
right: 0;
}

/* ellipsize name in 1on1 calls */
.participants-2 :deep(.videoContainer.promoted + .videoContainer-dummy .nameIndicator) {
padding: 12px 35%;
}

#videos .videoContainer.speaking:not(.videoView) :deep(.nameIndicator),
#videos .videoContainer.videoView.speaking :deep(.nameIndicator .microphone-icon) {
animation: pulse 1s;
animation-iteration-count: infinite;
}

@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: .3;
}
100% {
opacity: 1;
}
}

</style>
26 changes: 11 additions & 15 deletions src/components/CallView/Grid/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,7 @@ export default {

<style lang="scss" scoped>
.grid-main-wrapper {
--navigation-position: calc(var(--default-grid-baseline) * 2);
position: relative;
width: 100%;
}
Expand All @@ -1010,19 +1011,14 @@ export default {
height: 100%;
width: 100%;

grid-row-gap: 8px;
grid-column-gap: 8px;
grid-row-gap: var(--grid-gap);
grid-column-gap: var(--grid-gap);

&.stripe {
padding: 8px 8px 0 0;
padding: var(--grid-gap) var(--grid-gap) 0 0;
}
}

.empty-call-view {
position: relative;
padding: 16px;
}

.grid-wrapper {
width: 100%;
min-width: 0;
Expand Down Expand Up @@ -1103,32 +1099,32 @@ export default {
top: calc(50% - var(--default-clickable-area) / 2);

&__previous {
left: 8px;
left: calc(var(--default-grid-baseline) * 2);
}

&__next {
right: 8px;
right: calc(var(--default-grid-baseline) * 2);
}
}

.stripe-wrapper & {
position: absolute;
top: 16px;
top: calc(var(--navigation-position) + var(--grid-gap));

&__previous {
left: 8px;
left: var(--navigation-position);
}

&__next {
right: 16px;
right: calc(var(--navigation-position) + var(--grid-gap));
}
}
}

.stripe--collapse {
position: absolute !important;
top: calc(-1 * var(--default-clickable-area));
right: 0;
top: calc(-1 * (var(--default-clickable-area) + var(--navigation-position) / 2));
right: calc(var(--navigation-position) / 2) ;
}

.stripe--collapse,
Expand Down
38 changes: 16 additions & 22 deletions src/components/CallView/shared/LocalVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@

<template>
<div ref="videoContainer"
class="localVideoContainer videoContainer videoView"
class="localVideoContainer"
:class="videoContainerClass"
@mouseover="mouseover = true"
@mouseleave="mouseover = false"
@click="$emit('click-video')">
<div v-show="localMediaModel.attributes.videoEnabled"
:class="videoWrapperClass"
class="videoWrapper"
:style="videoWrapperStyle">
<video id="localVideo"
Expand All @@ -20,6 +19,9 @@
:class="fitVideo ? 'video--fit' : 'video--fill'"
class="video"
@playing="updateVideoAspectRatio" />
<NcLoadingIcon v-if="isNotConnected"
:size="avatarSize"
class="video-loading" />
</div>
<div v-if="!localMediaModel.attributes.videoEnabled && !isSidebar" class="avatar-container">
<VideoBackground v-if="isGrid || isStripe"
Expand All @@ -30,9 +32,9 @@
:name="displayName"
:source="actorType"
:size="avatarSize"
:loading="isNotConnected"
disable-menu
disable-tooltip
:class="avatarClass" />
disable-tooltip />
</div>

<div class="bottom-bar">
Expand All @@ -54,6 +56,7 @@ import { showError, showInfo, TOAST_PERMANENT_TIMEOUT } from '@nextcloud/dialogs
import { t } from '@nextcloud/l10n'

import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'

import VideoBackground from './VideoBackground.vue'
import AvatarWrapper from '../../AvatarWrapper/AvatarWrapper.vue'
Expand All @@ -71,6 +74,7 @@ export default {
AvatarWrapper,
NcButton,
VideoBackground,
NcLoadingIcon,
},

props: {
Expand Down Expand Up @@ -194,12 +198,6 @@ export default {
)
},

videoWrapperClass() {
return {
'icon-loading': this.isNotConnected,
}
},

avatarSize() {
if (this.isStripe || (!this.isBig && !this.isGrid)) {
return AVATAR.SIZE.LARGE
Expand All @@ -210,12 +208,6 @@ export default {
}
},

avatarClass() {
return {
'icon-loading': this.isNotConnected,
}
},

localStreamVideoError() {
return this.localMediaModel.attributes.localStream && this.localMediaModel.attributes.localStreamRequestVideoError
},
Expand Down Expand Up @@ -387,8 +379,8 @@ export default {

.video-container-big {
position: absolute;
width: calc(100% - 16px);
height: calc(100% - 8px);
width: calc(100% - var(--grid-gap) * 2);
height: calc(100% - var(--grid-gap));
display: flex;
flex-direction: column;

Expand All @@ -407,10 +399,12 @@ export default {
width: 100%;
}

.videoWrapper.icon-loading:after {
height: 60px;
width: 60px;
margin: -32px 0 0 -32px;
.video-loading {
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100%;
}

.video--fit {
Expand Down
2 changes: 1 addition & 1 deletion src/components/CallView/shared/VideoBottomBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ export default {
width: calc(100% - var(--default-clickable-area) * 2);
& .bottom-bar {
width: unset;
padding: calc(var(--default-grid-baseline) * 2);
padding: var(--default-grid-baseline);

&:hover {
background-color: rgba(0, 0, 0, 0.2);
Expand Down
2 changes: 1 addition & 1 deletion src/components/CallView/shared/VideoVue.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ describe('VideoVue.vue', () => {
* @param {boolean} expected Whether the loading icon is shown
*/
function assertLoadingIconIsShown(expected) {
const loadingIcon = wrapper.find('.icon-loading')
const loadingIcon = wrapper.findComponent({ name: 'NcLoadingIcon' })
expect(loadingIcon.exists()).toBe(expected)
}

Expand Down
Loading

0 comments on commit e8b57dd

Please sign in to comment.