Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add ability to collapse the grid view
To be able to focus on the video / screen of the current presenter.

Signed-off-by: Vincent Petry <[email protected]>
Co-authored-by: Marco Ambrosini <[email protected]>
  • Loading branch information
PVince81 and marcoambrosini committed Oct 19, 2020
commit b885bddae6426e2a841d62f8e909cf6ed0b1e3c3
23 changes: 23 additions & 0 deletions src/assets/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,26 @@ $chat-line-height: 1.6em;
transition: all 150ms ease-in-out;
}
}

.slide-down {
&-enter {
transform: translateY(50%);
opacity: 0;
}
&-enter-to {
transform: translateY(0);
opacity: 1;
}
&-leave {
transform: translateY(0);
opacity: 1;
}
&-leave-to {
transform: translateY(50%);
opacity: 0;
}
&-enter-active,
&-leave-active {
transition: all 150ms ease-in-out;
}
}
1 change: 1 addition & 0 deletions src/components/CallView/CallView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ export default {
width: 100%;
height: 100%;
top: 0;
overflow: hidden;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
Expand Down
233 changes: 137 additions & 96 deletions src/components/CallView/Grid/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,104 +20,122 @@
-->

<template>
<div class="wrapper" :style="wrapperStyle">
<div :class="{'pagination-wrapper': isStripe, 'wrapper': !isStripe}">
<button v-if="hasPreviousPage && gridWidth > 0 && isStripe && showVideoOverlay"
class="grid-navigation grid-navigation__previous"
@click="handleClickPrevious">
<ChevronLeft decorative
:size="24" />
</button>
<div
ref="grid"
class="grid"
:style="gridStyle"
@mousemove="handleMovement"
@keydown="handleMovement">
<template v-if="!devMode">
<EmptyCallView v-if="videos.length === 0 &&!isStripe" class="video" :is-grid="true" />
<template v-for="callParticipantModel in displayedVideos">
<Video
:key="callParticipantModel.attributes.peerId"
:class="{'video': !isStripe}"
:show-video-overlay="showVideoOverlay"
:token="token"
:model="callParticipantModel"
:is-grid="true"
:show-talking-highlight="!isStripe"
:is-stripe="isStripe"
:is-promoted="sharedDatas[callParticipantModel.attributes.peerId].promoted"
:is-selected="isSelected(callParticipantModel)"
:fit-video="false"
:video-container-aspect-ratio="videoContainerAspectRatio"
:video-background-blur="videoBackgroundBlur"
:shared-data="sharedDatas[callParticipantModel.attributes.peerId]"
@click-video="handleClickVideo($event, callParticipantModel.attributes.peerId)" />
</template>
<LocalVideo
v-if="!isStripe"
ref="localVideo"
class="video"
:is-grid="true"
:fit-video="isStripe"
:local-media-model="localMediaModel"
:video-container-aspect-ratio="videoContainerAspectRatio"
:local-call-participant-model="localCallParticipantModel"
@switchScreenToId="1"
@click-video="handleClickLocalVideo" />
</template>
<!-- Grid developer mode -->
<template v-else>
<div class="grid-main-wrapper">
<button v-if="isStripe"
class="stripe--collapse"
@click="stripeOpen = !stripeOpen">
<ChevronDown
v-if="stripeOpen"
fill-color="#ffffff"
decorative
:size="24" />
<ChevronUp
v-else
fill-color="#ffffff"
decorative
:size="24" />
</button>
<transition name="slide-down">
<div v-if="!isStripe || stripeOpen" class="wrapper" :style="wrapperStyle">
<div :class="{'pagination-wrapper': isStripe, 'wrapper': !isStripe}">
<button v-if="hasPreviousPage && gridWidth > 0 && isStripe && showVideoOverlay"
class="grid-navigation grid-navigation__previous"
@click="handleClickPrevious">
<ChevronLeft decorative
:size="24" />
</button>
<div
v-for="video in displayedVideos"
:key="video"
class="dev-mode-video video"
v-text="video" />
<h1 class="dev-mode__title">
Dev mode on ;-)
</h1>
</template>
ref="grid"
class="grid"
:style="gridStyle"
@mousemove="handleMovement"
@keydown="handleMovement">
<template v-if="!devMode">
<EmptyCallView v-if="videos.length === 0 &&!isStripe" class="video" :is-grid="true" />
<template v-for="callParticipantModel in displayedVideos">
<Video
:key="callParticipantModel.attributes.peerId"
:class="{'video': !isStripe}"
:show-video-overlay="showVideoOverlay"
:token="token"
:model="callParticipantModel"
:is-grid="true"
:show-talking-highlight="!isStripe"
:is-stripe="isStripe"
:is-promoted="sharedDatas[callParticipantModel.attributes.peerId].promoted"
:is-selected="isSelected(callParticipantModel)"
:fit-video="false"
:video-container-aspect-ratio="videoContainerAspectRatio"
:video-background-blur="videoBackgroundBlur"
:shared-data="sharedDatas[callParticipantModel.attributes.peerId]"
@click-video="handleClickVideo($event, callParticipantModel.attributes.peerId)" />
</template>
<LocalVideo
v-if="!isStripe"
ref="localVideo"
class="video"
:is-grid="true"
:fit-video="isStripe"
:local-media-model="localMediaModel"
:video-container-aspect-ratio="videoContainerAspectRatio"
:local-call-participant-model="localCallParticipantModel"
@switchScreenToId="1"
@click-video="handleClickLocalVideo" />
</template>
<!-- Grid developer mode -->
<template v-else>
<div
v-for="video in displayedVideos"
:key="video"
class="dev-mode-video video"
v-text="video" />
<h1 class="dev-mode__title">
Dev mode on ;-)
</h1>
</template>
</div>
<button v-if="hasNextPage && gridWidth > 0 && isStripe && showVideoOverlay"
class="grid-navigation grid-navigation__next"
@click="handleClickNext">
<ChevronRight decorative
:size="24" />
</button>
</div>
<LocalVideo
v-if="isStripe"
ref="localVideo"
class="video"
:fit-video="true"
:is-stripe="true"
:local-media-model="localMediaModel"
:video-container-aspect-ratio="videoContainerAspectRatio"
:local-call-participant-model="localCallParticipantModel"
@switchScreenToId="1"
@click-video="handleClickLocalVideo" />
<!-- page indicator (disabled) -->
<div
v-if="numberOfPages !== 0 && hasPagination && false"
class="pages-indicator">
<div v-for="(page, index) in numberOfPages"
:key="index"
class="pages-indicator__dot"
:class="{'pages-indicator__dot--active': index === currentPage }" />
</div>
<div v-if="devMode" class="dev-mode__data">
<p>GRID INFO</p>
<p>Videos (total): {{ videosCount }}</p>
<p>Displayed videos n: {{ displayedVideos.length }}</p>
<p>Max per page: ~{{ videosCap }}</p>
<p>Grid width: {{ gridWidth }}</p>
<p>Grid height: {{ gridHeight }}</p>
<p>Min video width: {{ minWidth }} </p>
<p>Min video Height: {{ minHeight }} </p>
<p>Grid aspect ratio: {{ gridAspectRatio }}</p>
<p>Number of pages: {{ numberOfPages }}</p>
<p>Current page: {{ currentPage }}</p>
</div>
</div>
<button v-if="hasNextPage && gridWidth > 0 && isStripe && showVideoOverlay"
class="grid-navigation grid-navigation__next"
@click="handleClickNext">
<ChevronRight decorative
:size="24" />
</button>
</div>
<LocalVideo
v-if="isStripe"
ref="localVideo"
class="video"
:fit-video="true"
:is-stripe="true"
:local-media-model="localMediaModel"
:video-container-aspect-ratio="videoContainerAspectRatio"
:local-call-participant-model="localCallParticipantModel"
@switchScreenToId="1"
@click-video="handleClickLocalVideo" />
<!-- page indicator (disabled) -->
<div
v-if="numberOfPages !== 0 && hasPagination && false"
class="pages-indicator">
<div v-for="(page, index) in numberOfPages"
:key="index"
class="pages-indicator__dot"
:class="{'pages-indicator__dot--active': index === currentPage }" />
</div>
<div v-if="devMode" class="dev-mode__data">
<p>GRID INFO</p>
<p>Videos (total): {{ videosCount }}</p>
<p>Displayed videos n: {{ displayedVideos.length }}</p>
<p>Max per page: ~{{ videosCap }}</p>
<p>Grid width: {{ gridWidth }}</p>
<p>Grid height: {{ gridHeight }}</p>
<p>Min video width: {{ minWidth }} </p>
<p>Min video Height: {{ minHeight }} </p>
<p>Grid aspect ratio: {{ gridAspectRatio }}</p>
<p>Number of pages: {{ numberOfPages }}</p>
<p>Current page: {{ currentPage }}</p>
</div>
</transition>
</div>
</template>

Expand All @@ -130,6 +148,8 @@ import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import EmptyCallView from '../shared/EmptyCallView'
import ChevronRight from 'vue-material-design-icons/ChevronRight'
import ChevronLeft from 'vue-material-design-icons/ChevronLeft'
import ChevronUp from 'vue-material-design-icons/ChevronUp'
import ChevronDown from 'vue-material-design-icons/ChevronDown'

export default {
name: 'Grid',
Expand All @@ -140,6 +160,8 @@ export default {
EmptyCallView,
ChevronRight,
ChevronLeft,
ChevronUp,
ChevronDown,
},

props: {
Expand Down Expand Up @@ -242,6 +264,8 @@ export default {
showVideoOverlay: true,
// Timer for the videos bottom bar
showVideoOverlayTimer: null,
// Whether the stripe is open (true) or collapsed (false)
stripeOpen: true,
}
},

Expand Down Expand Up @@ -655,6 +679,13 @@ export default {
</script>

<style lang="scss" scoped>
@import '../../../assets/variables.scss';

.grid-main-wrapper {
position: relative;
width: 100%;
background-color: var(--color-text-maxcontrast);
}

.wrapper {
width: 100%;
Expand Down Expand Up @@ -774,4 +805,14 @@ export default {
}
}

/** FIXME: replace with nextcloud-vue button */
.stripe--collapse, .stripe--collapse:active {
position: absolute;
top: -50px;
right: 0;
z-index: 10;
border: 0;
background: none;
}

</style>