summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDorraJaouad <dorra.jaoued7@gmail.com>2024-03-22 16:57:16 +0100
committerDorraJaouad <dorra.jaoued7@gmail.com>2024-03-26 16:31:16 +0100
commit5f2881a6df75b9662f6add8780694ff0260b5b62 (patch)
tree0837eaa7f1b1e60d68949877c20f7fd09e890d1a
parent336b1e9dcc824b3d6bae42b5686f446448e15622 (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.vue95
-rw-r--r--src/components/CallView/shared/PresenterOverlay.vue163
-rw-r--r--src/components/CallView/shared/VideoVue.vue2
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;