diff options
author | DorraJaouad <dorra.jaoued7@gmail.com> | 2024-03-22 16:57:16 +0100 |
---|---|---|
committer | DorraJaouad <dorra.jaoued7@gmail.com> | 2024-03-26 16:31:16 +0100 |
commit | 5f2881a6df75b9662f6add8780694ff0260b5b62 (patch) | |
tree | 0837eaa7f1b1e60d68949877c20f7fd09e890d1a | |
parent | 336b1e9dcc824b3d6bae42b5686f446448e15622 (diff) |
Fix(PresenterOverlay): move PresenterOverlay to a different component and add grabbing effects
Signed-off-by: DorraJaouad <dorra.jaoued7@gmail.com>
-rw-r--r-- | src/components/CallView/CallView.vue | 95 | ||||
-rw-r--r-- | src/components/CallView/shared/PresenterOverlay.vue | 163 | ||||
-rw-r--r-- | src/components/CallView/shared/VideoVue.vue | 2 |
3 files changed, 180 insertions, 80 deletions
diff --git a/src/components/CallView/CallView.vue b/src/components/CallView/CallView.vue index e278f0544..d81aa5ccf 100644 --- a/src/components/CallView/CallView.vue +++ b/src/components/CallView/CallView.vue @@ -75,36 +75,13 @@ :shared-data="sharedDatas[shownRemoteScreenPeerId]" is-big /> <!-- presenter overlay --> - <VueDraggableResizable v-if="shouldShowPresenterOverlay" - :key="presenterOverlaySize" - parent - :resizable="false" - :h="presenterOverlaySize" - :w="presenterOverlaySize" - :x="10" - :y="10"> - <VideoVue class="presenter-overlay__video" - :token="token" - :model="shownRemoteScreenCallParticipantModel" - :shared-data="sharedDatas[shownRemoteScreenPeerId]" - is-presenter-overlay - un-selectable - hide-bottom-bar - @click-presenter="toggleShowPresenterOverlay" /> - </VueDraggableResizable> - <!-- presenter button when presenter overlay is collapsed --> - <NcButton v-else-if="isPresenterCollapsed" - :aria-label="t('spreed', 'Show presenter')" - :title="t('spreed', 'Show presenter')" - class="presenter-overlay--collapse" - type="tertiary-no-background" - @click="toggleShowPresenterOverlay"> - <template #icon> - <AccountBox fill-color="#ffffff" :size="20" /> - </template> - </NcButton> + <PresenterOverlay v-if="shouldShowPresenterOverlay" + :token="token" + :model="shownRemoteScreenCallParticipantModel" + :shared-data="sharedDatas[shownRemoteScreenPeerId]" + :is-collapsed="!showPresenterOverlay" + @click="toggleShowPresenterOverlay" /> </template> - <!-- Promoted "autopilot" mode --> <VideoVue v-else-if="promotedParticipantModel" :key="promotedParticipantModel.attributes.peerId" @@ -159,19 +136,15 @@ <script> import debounce from 'debounce' -import VueDraggableResizable from 'vue-draggable-resizable' - -import AccountBox from 'vue-material-design-icons/AccountBoxOutline.vue' import { getCapabilities } from '@nextcloud/capabilities' import { showMessage } from '@nextcloud/dialogs' import { subscribe, unsubscribe } from '@nextcloud/event-bus' -import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' - import Grid from './Grid/Grid.vue' import EmptyCallView from './shared/EmptyCallView.vue' import LocalVideo from './shared/LocalVideo.vue' +import PresenterOverlay from './shared/PresenterOverlay.vue' import ReactionToaster from './shared/ReactionToaster.vue' import Screen from './shared/Screen.vue' import VideoVue from './shared/VideoVue.vue' @@ -190,13 +163,11 @@ export default { name: 'CallView', components: { - AccountBox, EmptyCallView, ViewerOverlayCallView, - VueDraggableResizable, Grid, LocalVideo, - NcButton, + PresenterOverlay, ReactionToaster, Screen, VideoVue, @@ -242,9 +213,9 @@ export default { isBackgroundBlurred: true, showPresenterOverlay: true, debounceFetchPeers: () => {}, - presenterOverlaySize: 128, } }, + computed: { promotedParticipantModel() { return this.callParticipantModels.find((callParticipantModel) => this.sharedDatas[callParticipantModel.attributes.peerId].promoted) @@ -367,12 +338,8 @@ export default { }) }, - isPresenterCollapsed() { - return !this.showPresenterOverlay && this.shownRemoteScreenCallParticipantModel.attributes.videoAvailable - }, - shouldShowPresenterOverlay() { - return this.showPresenterOverlay && this.isModelWithVideo(this.shownRemoteScreenCallParticipantModel) + return this.shownRemoteScreenCallParticipantModel.attributes.videoAvailable || this.isModelWithVideo(this.shownRemoteScreenCallParticipantModel) }, @@ -380,6 +347,7 @@ export default { return this.sharedDatas[this.shownRemoteScreenPeerId]?.remoteVideoBlocker?.isVideoEnabled() }, }, + watch: { 'localCallParticipantModel.attributes.peerId'(newValue, previousValue) { const index = this.screens.indexOf(previousValue) @@ -462,12 +430,14 @@ export default { this.showPresenterOverlay = value }, }, + created() { // Ensure that data is properly initialized before mounting the // subviews. this.updateDataFromCallParticipantModels(this.callParticipantModels) this.isBackgroundBlurred = BrowserStorage.getItem('background-blurred') !== 'false' }, + mounted() { this.debounceFetchPeers = debounce(this.fetchPeers, 1500) EventBus.$on('refresh-peer-list', this.debounceFetchPeers) @@ -476,9 +446,8 @@ export default { subscribe('switch-screen-to-id', this._switchScreenToId) subscribe('set-background-blurred', this.setBackgroundBlurred) - - window.addEventListener('resize', this.updateSize) }, + beforeDestroy() { this.debounceFetchPeers.clear?.() EventBus.$off('refresh-peer-list', this.debounceFetchPeers) @@ -487,9 +456,8 @@ export default { unsubscribe('switch-screen-to-id', this._switchScreenToId) unsubscribe('set-background-blurred', this.setBackgroundBlurred) - - window.removeEventListener('resize', this.updateSize) }, + methods: { /** * Updates data properties that depend on the CallParticipantModels. @@ -769,9 +737,6 @@ export default { } }, - updateSize() { - this.presenterOverlaySize = Math.min(Math.max(window.innerWidth * 0.1, 100), 242) - }, }, } </script> @@ -796,36 +761,6 @@ export default { } } -.presenter-overlay__video { - position: relative; - --max-size: 242px; - --min-size: 100px; - width: 10vw; - height: 10vw; - max-width: var(--max-size); - max-height: var(--max-size); - min-width: var(--min-size); - min-height: var(--min-size); - z-index: 10; -} - -.presenter-overlay--collapse { - position: absolute !important; - opacity: .7; - bottom: 48px; - right: 0; - - #call-container:hover & { - background-color: rgba(0, 0, 0, 0.1) !important; - - &:hover, - &:focus { - opacity: 1; - background-color: rgba(0, 0, 0, 0.2) !important; - } - } -} - #videos { position: absolute; width: 100%; diff --git a/src/components/CallView/shared/PresenterOverlay.vue b/src/components/CallView/shared/PresenterOverlay.vue new file mode 100644 index 000000000..b4d3e8251 --- /dev/null +++ b/src/components/CallView/shared/PresenterOverlay.vue @@ -0,0 +1,163 @@ +<!-- + - @copyright Copyright (c) 2024 Dorra Jaouad <dorra.jaoued1@gmail.com> + - + - @license AGPL-3.0-or-later + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + --> +<template> + <VueDraggableResizable v-if="!isCollapsed" + :key="presenterOverlaySize" + parent + :resizable="false" + :h="presenterOverlaySize" + :w="presenterOverlaySize" + :x="10" + :y="10" + @dragging="isDragging = true" + @dragstop="isDragging = false"> + <VideoVue :token="token" + :class="{ 'dragging': isDragging }" + class="presenter-overlay__video" + :model="model" + :shared-data="sharedData" + is-presenter-overlay + un-selectable + hide-bottom-bar + @click-presenter="$emit('click')" /> + </VueDraggableResizable> + + <!-- presenter button when presenter overlay is collapsed --> + <NcButton v-else + :aria-label="t('spreed', 'Show presenter')" + :title="t('spreed', 'Show presenter')" + class="presenter-overlay--collapsed" + type="tertiary-no-background" + @click="$emit('click')"> + <template #icon> + <AccountBox fill-color="#ffffff" :size="20" /> + </template> + </NcButton> +</template> + +<script> + +import VueDraggableResizable from 'vue-draggable-resizable' + +import AccountBox from 'vue-material-design-icons/AccountBoxOutline.vue' + +import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' + +import VideoVue from './VideoVue.vue' + +export default { + name: 'PresenterOverlay', + + components: { + AccountBox, + VueDraggableResizable, + NcButton, + VideoVue, + }, + + props: { + token: { + type: String, + required: true, + }, + + model: { + type: Object, + required: true, + }, + + sharedData: { + type: Object, + required: true, + }, + + isCollapsed: { + type: Boolean, + required: true, + }, + }, + + emits: ['click'], + + data() { + return { + presenterOverlaySize: 128, + isDragging: false, + } + }, + + mounted() { + window.addEventListener('resize', this.updateSize) + }, + + beforeDestroy() { + window.removeEventListener('resize', this.updateSize) + }, + + methods: { + updateSize() { + this.presenterOverlaySize = Math.min(Math.max(window.innerWidth * 0.1, 100), 242) + }, + }, +} +</script> + +<style lang="scss" scoped> +.presenter-overlay__video { + position: relative; + --max-size: 242px; + --min-size: 100px; + width: 10vw; + height: 10vw; + max-width: var(--max-size); + max-height: var(--max-size); + min-width: var(--min-size); + min-height: var(--min-size); + z-index: 10; + + &:hover { + cursor: grab; + } + + &.dragging { + cursor: grabbing; + } +} + +.presenter-overlay--collapsed { + position: absolute !important; + opacity: .7; + bottom: 48px; + right: 0; + + #call-container:hover & { + background-color: rgba(0, 0, 0, 0.1) !important; + + &:hover, + &:focus { + opacity: 1; + background-color: rgba(0, 0, 0, 0.2) !important; + } + } +} + +:deep(div) { + cursor: inherit; +} +</style> diff --git a/src/components/CallView/shared/VideoVue.vue b/src/components/CallView/shared/VideoVue.vue index 86808d0e3..515e52209 100644 --- a/src/components/CallView/shared/VideoVue.vue +++ b/src/components/CallView/shared/VideoVue.vue @@ -727,6 +727,7 @@ export default { content: ''; box-shadow: inset 0 0 0 3px white; cursor: pointer; + z-index: 1; } .presenter-icon__hide { @@ -739,6 +740,7 @@ export default { border-radius: 50%; padding: 6px; width: 44px; + z-index: 2; &:hover { cursor: pointer; |