Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2022-11-07 14:56:04 +0300
committerGitHub <noreply@github.com>2022-11-07 14:56:04 +0300
commit86a150f90aee066a8666012831e0f6e8f70e62b9 (patch)
treeb5b981b049170bbb1d03edac06b22bbeed556501
parentfbd410fedb04542cd347459f245a848333541a3b (diff)
parent15594405be5f66f38f817f4b17e48e4a25074a4a (diff)
Merge pull request #8209 from nextcloud/feature/6889/one-action-menu-only-in-calls
Reduce two menus to one
-rw-r--r--src/components/CallView/shared/LocalMediaControls.vue112
-rw-r--r--src/components/TopBar/TopBar.vue210
-rw-r--r--src/components/TopBar/TopBarMenu.vue396
3 files changed, 417 insertions, 301 deletions
diff --git a/src/components/CallView/shared/LocalMediaControls.vue b/src/components/CallView/shared/LocalMediaControls.vue
index 437de45e6..ac68a95dd 100644
--- a/src/components/CallView/shared/LocalMediaControls.vue
+++ b/src/components/CallView/shared/LocalMediaControls.vue
@@ -167,61 +167,11 @@
@click.stop="toggleHandRaised">
<template #icon>
<!-- The following icon is much bigger than all the others
- so we reduce its size -->
+ so we reduce its size -->
<HandBackLeft :size="18"
fill-color="#ffffff" />
</template>
</NcButton>
- <NcActions v-if="showActions"
- v-tooltip="t('spreed', 'More actions')"
- :container="container"
- :aria-label="t('spreed', 'More actions')">
- <template #icon>
- <DotsHorizontal :size="20"
- fill-color="#ffffff" />
- </template>
-
- <NcActionButton :close-after-click="true"
- @click="toggleHandRaised">
- <!-- The following icon is much bigger than all the others
- so we reduce its size -->
- <template #icon>
- <HandBackLeft :size="18" />
- </template>
- {{ raiseHandButtonLabel }}
- </NcActionButton>
- <NcActionButton v-if="isVirtualBackgroundAvailable"
- :close-after-click="true"
- @click="toggleVirtualBackground">
- <template #icon>
- <BlurOff v-if="isVirtualBackgroundEnabled"
- :size="20" />
- <Blur v-else
- :size="20" />
- </template>
- {{ toggleVirtualBackgroundButtonLabel }}
- </NcActionButton>
- <!-- Call layout switcher -->
- <NcActionButton v-if="isInCall"
- :close-after-click="true"
- @click="changeView">
- <template #icon>
- <GridView v-if="!isGrid"
- :size="20" />
- <PromotedView v-else
- :size="20" />
- </template>
- {{ changeViewText }}
- </NcActionButton>
- <NcActionSeparator />
- <NcActionButton :close-after-click="true"
- @click="showSettings">
- <template #icon>
- <Cog :size="20" />
- </template>
- {{ t('spreed', 'Devices settings') }}
- </NcActionButton>
- </NcActions>
</div>
</div>
</template>
@@ -231,31 +181,26 @@ import escapeHtml from 'escape-html'
import { emit } from '@nextcloud/event-bus'
import { showMessage } from '@nextcloud/dialogs'
import CancelPresentation from '../../missingMaterialDesignIcons/CancelPresentation.vue'
-import Cog from 'vue-material-design-icons/Cog.vue'
-import DotsHorizontal from 'vue-material-design-icons/DotsHorizontal.vue'
-import GridView from '../../missingMaterialDesignIcons/GridView.vue'
import HandBackLeft from 'vue-material-design-icons/HandBackLeft.vue'
import Microphone from 'vue-material-design-icons/Microphone.vue'
import MicrophoneOff from 'vue-material-design-icons/MicrophoneOff.vue'
import Monitor from 'vue-material-design-icons/Monitor.vue'
import PresentToAll from '../../missingMaterialDesignIcons/PresentToAll.vue'
-import PromotedView from '../../missingMaterialDesignIcons/PromotedView.vue'
import VideoIcon from 'vue-material-design-icons/Video.vue'
import VideoOff from 'vue-material-design-icons/VideoOff.vue'
-import Blur from 'vue-material-design-icons/Blur.vue'
-import BlurOff from 'vue-material-design-icons/BlurOff.vue'
import NcPopover from '@nextcloud/vue/dist/Components/NcPopover.js'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
import { PARTICIPANT } from '../../../constants.js'
import SpeakingWhileMutedWarner from '../../../utils/webrtc/SpeakingWhileMutedWarner.js'
import NetworkStrength2Alert from 'vue-material-design-icons/NetworkStrength2Alert.vue'
-import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
-import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'
-import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import { callAnalyzer } from '../../../utils/webrtc/index.js'
import { CONNECTION_QUALITY } from '../../../utils/webrtc/analyzers/PeerConnectionAnalyzer.js'
import isInCall from '../../../mixins/isInCall.js'
+import Blur from 'vue-material-design-icons/Blur.vue'
+import BlurOff from 'vue-material-design-icons/BlurOff.vue'
+import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
+import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
+import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
export default {
@@ -267,22 +212,17 @@ export default {
components: {
NetworkStrength2Alert,
NcPopover,
- NcActions,
- NcActionSeparator,
- NcActionButton,
- NcButton,
CancelPresentation,
- Cog,
- DotsHorizontal,
- GridView,
HandBackLeft,
Microphone,
MicrophoneOff,
PresentToAll,
- PromotedView,
VideoIcon,
VideoOff,
Monitor,
+ NcButton,
+ NcActions,
+ NcActionButton,
Blur,
BlurOff,
},
@@ -337,19 +277,6 @@ export default {
},
computed: {
- raiseHandButtonLabel() {
- if (!this.model.attributes.raisedHand.state) {
- if (this.disableKeyboardShortcuts) {
- return t('spreed', 'Raise hand')
- }
- return t('spreed', 'Raise hand (R)')
- }
- if (this.disableKeyboardShortcuts) {
- return t('spreed', 'Lower hand')
- }
- return t('spreed', 'Lower hand (R)')
- },
-
isVirtualBackgroundAvailable() {
return this.model.attributes.virtualBackgroundAvailable
},
@@ -667,18 +594,6 @@ export default {
return tooltip
},
- changeViewText() {
- if (this.isGrid) {
- return t('spreed', 'Speaker view')
- } else {
- return t('spreed', 'Grid view')
- }
- },
-
- isGrid() {
- return this.$store.getters.isGrid
- },
-
disableKeyboardShortcuts() {
return OCP.Accessibility.disableKeyboardShortcuts()
},
@@ -732,10 +647,6 @@ export default {
this.$refs.volumeIndicator.style.height = height + 'px'
},
- showSettings() {
- emit('show-settings')
- },
-
/**
* This method executes on spacebar keydown and keyup
*/
@@ -910,11 +821,6 @@ export default {
dismissQualityWarningTooltip() {
this.$store.dispatch('dismissQualityWarningTooltip')
},
-
- changeView() {
- this.$store.dispatch('setCallViewMode', { isGrid: !this.isGrid })
- this.$store.dispatch('selectedVideoPeerId', null)
- },
},
}
</script>
diff --git a/src/components/TopBar/TopBar.vue b/src/components/TopBar/TopBar.vue
index 4e417af7b..2e8429ad8 100644
--- a/src/components/TopBar/TopBar.vue
+++ b/src/components/TopBar/TopBar.vue
@@ -61,71 +61,17 @@
:show-actions="!isSidebar"
:screen-sharing-button-hidden="isSidebar"
:local-call-participant-model="localCallParticipantModel" />
+
+ <!-- TopBar menu -->
+ <TopBarMenu :token="token"
+ :show-actions="!isSidebar"
+ :is-sidebar="isSidebar"
+ :model="localMediaModel" />
+
<div class="top-bar__buttons">
<CallButton class="top-bar__button" />
- <!-- Vertical line -->
- <div v-if="!isSidebar && isInCall"
- class="top-bar__separator" />
-
<!-- sidebar toggle -->
- <NcActions v-if="!isSidebar"
- v-shortkey.once="disableKeyboardShortcuts ? null : ['f']"
- class="top-bar__button"
- :aria-label="t('spreed', 'Conversation actions')"
- :container="container"
- @shortkey.native="toggleFullscreen">
- <template #icon>
- <span :class="{'top-bar__button__force-white': isInCall}">
- <Cog :size="20" />
- </span>
- </template>
- <NcActionButton :icon="iconFullscreen"
- :aria-label="t('spreed', 'Toggle fullscreen')"
- :close-after-click="true"
- @click="toggleFullscreen">
- {{ labelFullscreen }}
- </NcActionButton>
- <NcActionSeparator v-if="showModerationOptions" />
- <NcActionLink v-if="isFileConversation"
- :href="linkToFile">
- <template #icon>
- <File :size="20" />
- </template>
- {{ t('spreed', 'Go to file') }}
- </NcActionLink>
- <template v-if="showModerationOptions">
- <NcActionButton :close-after-click="true"
- icon="icon-rename"
- @click="handleRenameConversation">
- {{ t('spreed', 'Rename conversation') }}
- </NcActionButton>
- </template>
- <NcActionButton v-if="!isOneToOneConversation"
- icon="icon-clippy"
- :close-after-click="true"
- @click="handleCopyLink">
- {{ t('spreed', 'Copy link') }}
- </NcActionButton>
- <template v-if="showModerationOptions && canFullModerate && isInCall">
- <NcActionSeparator />
- <NcActionButton :close-after-click="true"
- @click="forceMuteOthers">
- <template #icon>
- <MicrophoneOff :size="20" />
- </template>
- {{ t('spreed', 'Mute others') }}
- </NcActionButton>
- </template>
- <NcActionSeparator v-if="showModerationOptions" />
- <NcActionButton :close-after-click="true"
- @click="openConversationSettings">
- <template #icon>
- <Cog :size="20" />
- </template>
- {{ t('spreed', 'Conversation settings') }}
- </NcActionButton>
- </NcActions>
<NcActions v-if="showOpenSidebarButton"
class="top-bar__button"
close-after-click="true"
@@ -156,29 +102,25 @@
</template>
<script>
-import { showError, showSuccess, showMessage } from '@nextcloud/dialogs'
+import { showMessage } from '@nextcloud/dialogs'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js'
import CallButton from './CallButton.vue'
import BrowserStorage from '../../services/BrowserStorage.js'
-import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
-import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'
-import File from 'vue-material-design-icons/File.vue'
import MenuPeople from '../missingMaterialDesignIcons/MenuPeople.vue'
import MessageText from 'vue-material-design-icons/MessageText.vue'
-import MicrophoneOff from 'vue-material-design-icons/MicrophoneOff.vue'
-import { CONVERSATION, PARTICIPANT } from '../../constants.js'
+import { CONVERSATION } from '../../constants.js'
import { generateUrl } from '@nextcloud/router'
-import { callParticipantCollection, localCallParticipantModel, localMediaModel } from '../../utils/webrtc/index.js'
+import { localCallParticipantModel, localMediaModel } from '../../utils/webrtc/index.js'
import { emit } from '@nextcloud/event-bus'
import ConversationIcon from '../ConversationIcon.vue'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
import richEditor from '@nextcloud/vue/dist/Mixins/richEditor.js'
import userStatus from '../../mixins/userStatus.js'
import LocalMediaControls from '../CallView/shared/LocalMediaControls.vue'
-import Cog from 'vue-material-design-icons/Cog.vue'
import getParticipants from '../../mixins/getParticipants.js'
+import TopBarMenu from './TopBarMenu.vue'
export default {
name: 'TopBar',
@@ -190,17 +132,13 @@ export default {
components: {
NcActionButton,
NcActions,
- NcActionLink,
NcCounterBubble,
CallButton,
- NcActionSeparator,
- File,
MenuPeople,
MessageText,
- MicrophoneOff,
ConversationIcon,
LocalMediaControls,
- Cog,
+ TopBarMenu,
},
mixins: [
@@ -238,60 +176,14 @@ export default {
return this.$store.getters.getMainContainerSelector()
},
- isFullscreen() {
- return this.$store.getters.isFullscreen()
- },
-
- iconFullscreen() {
- if (this.isInCall) {
- return 'forced-white icon-fullscreen'
- }
- return 'icon-fullscreen'
- },
-
- labelFullscreen() {
- if (this.isFullscreen) {
- return t('spreed', 'Exit fullscreen (F)')
- }
- return t('spreed', 'Fullscreen (F)')
- },
-
showOpenSidebarButton() {
return !this.$store.getters.getSidebarStatus
},
- isFileConversation() {
- return this.conversation.objectType === 'file' && this.conversation.objectId
- },
-
isOneToOneConversation() {
return this.conversation.type === CONVERSATION.TYPE.ONE_TO_ONE
},
- linkToFile() {
- if (this.isFileConversation) {
- return window.location.protocol + '//' + window.location.host + generateUrl('/f/' + this.conversation.objectId)
- } else {
- return ''
- }
- },
-
- participantType() {
- return this.conversation.participantType
- },
-
- canFullModerate() {
- return this.participantType === PARTICIPANT.TYPE.OWNER || this.participantType === PARTICIPANT.TYPE.MODERATOR
- },
-
- canModerate() {
- return this.canFullModerate || this.participantType === PARTICIPANT.TYPE.GUEST_MODERATOR
- },
-
- showModerationOptions() {
- return !this.isOneToOneConversation && this.canModerate
- },
-
token() {
return this.$store.getters.getToken()
},
@@ -323,11 +215,6 @@ export default {
}
},
- conversationHasSettings() {
- return this.conversation.type === CONVERSATION.TYPE.GROUP
- || this.conversation.type === CONVERSATION.TYPE.PUBLIC
- },
-
renderedDescription() {
return this.renderContent(this.conversation.description)
},
@@ -361,10 +248,6 @@ export default {
return !peer.sessionIds.length
} else return false
},
-
- disableKeyboardShortcuts() {
- return OCP.Accessibility.disableKeyboardShortcuts()
- },
},
watch: {
@@ -439,67 +322,6 @@ export default {
BrowserStorage.setItem('sidebarOpen', 'true')
},
- fullScreenChanged() {
- this.$store.dispatch(
- 'setIsFullscreen',
- document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement
- )
- },
-
- toggleFullscreen() {
- if (this.isFullscreen) {
- this.disableFullscreen()
- this.$store.dispatch('setIsFullscreen', false)
- } else {
- this.enableFullscreen()
- this.$store.dispatch('setIsFullscreen', true)
- }
- },
-
- enableFullscreen() {
- const fullscreenElem = document.getElementById('content-vue')
-
- if (fullscreenElem.requestFullscreen) {
- fullscreenElem.requestFullscreen()
- } else if (fullscreenElem.webkitRequestFullscreen) {
- fullscreenElem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)
- } else if (fullscreenElem.mozRequestFullScreen) {
- fullscreenElem.mozRequestFullScreen()
- } else if (fullscreenElem.msRequestFullscreen) {
- fullscreenElem.msRequestFullscreen()
- }
- },
-
- disableFullscreen() {
- if (document.exitFullscreen) {
- document.exitFullscreen()
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen()
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen()
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen()
- }
- },
-
- async handleCopyLink() {
- try {
- await navigator.clipboard.writeText(this.linkToConversation)
- showSuccess(t('spreed', 'Conversation link copied to clipboard'))
- } catch (error) {
- showError(t('spreed', 'The link could not be copied'))
- }
- },
- handleRenameConversation() {
- this.$store.dispatch('isRenamingConversation', true)
- this.$store.dispatch('showSidebar')
- },
- forceMuteOthers() {
- callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
- callParticipantModel.forceMute()
- })
- },
-
openConversationSettings() {
emit('show-conversation-settings', { token: this.token })
},
@@ -561,14 +383,6 @@ export default {
right: 4px;
pointer-events: none;
}
-
- &__separator {
- top: 4px;
- border-left: 1px solid white;
- height: 36px;
- margin: auto 6px;
- opacity: 0.5;
- }
}
.conversation-icon {
diff --git a/src/components/TopBar/TopBarMenu.vue b/src/components/TopBar/TopBarMenu.vue
new file mode 100644
index 000000000..a43b212b8
--- /dev/null
+++ b/src/components/TopBar/TopBarMenu.vue
@@ -0,0 +1,396 @@
+<!--
+ - @copyright Copyright (c) 2022 Marco Ambrosini <marcoambrosini@icloud.com>
+ -
+ - @author Marco Ambrosini <marcoambrosini@icloud.com>
+ -
+ - @license GNU AGPL version 3 or any later version
+ -
+ - 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>
+ <NcActions v-if="!isSidebar"
+ v-shortkey.once="disableKeyboardShortcuts ? null : ['f']"
+ v-tooltip="t('spreed', 'Conversation actions')"
+ class="top-bar__button"
+ :aria-label="t('spreed', 'Conversation actions')"
+ :container="container"
+ @shortkey.native="toggleFullscreen">
+ <!-- White icon if in call -->
+ <template v-if="isInCall" #icon>
+ <DotsHorizontal :size="20"
+ fill-color="#ffffff" />
+ </template>
+ <template v-if="showActions && isInCall">
+ <!-- Raise hand -->
+ <NcActionButton :close-after-click="true"
+ @click="toggleHandRaised">
+ <!-- The following icon is much bigger than all the others
+ so we reduce its size -->
+ <template #icon>
+ <HandBackLeft :size="18" />
+ </template>
+ {{ raiseHandButtonLabel }}
+ </NcActionButton>
+ <!-- Blur background -->
+ <NcActionButton v-if="isVirtualBackgroundAvailable"
+ :close-after-click="true"
+ @click="toggleVirtualBackground">
+ <template #icon>
+ <BlurOff v-if="isVirtualBackgroundEnabled"
+ :size="20" />
+ <Blur v-else
+ :size="20" />
+ </template>
+ {{ toggleVirtualBackgroundButtonLabel }}
+ </NcActionButton>
+ <!-- Mute others -->
+ <template v-if="showModerationOptions && canFullModerate">
+ <NcActionButton :close-after-click="true"
+ @click="forceMuteOthers">
+ <template #icon>
+ <MicrophoneOff :size="20" />
+ </template>
+ {{ t('spreed', 'Mute others') }}
+ </NcActionButton>
+ </template>
+ <!-- Device settings -->
+ <NcActionButton :close-after-click="true"
+ @click="showSettings">
+ <template #icon>
+ <VideoIcon :size="20" />
+ </template>
+ {{ t('spreed', 'Devices settings') }}
+ </NcActionButton>
+ <NcActionSeparator />
+ </template>
+ <!-- Call layout switcher -->
+ <NcActionButton v-if="showActions && isInCall"
+ :close-after-click="true"
+ @click="changeView">
+ <template #icon>
+ <GridView v-if="!isGrid"
+ :size="20" />
+ <PromotedView v-else
+ :size="20" />
+ </template>
+ {{ changeViewText }}
+ </NcActionButton>
+ <NcActionButton :icon="iconFullscreen"
+ :aria-label="t('spreed', 'Toggle fullscreen')"
+ :close-after-click="true"
+ @click="toggleFullscreen">
+ {{ labelFullscreen }}
+ </NcActionButton>
+ <NcActionLink v-if="isFileConversation"
+ :href="linkToFile">
+ <template #icon>
+ <File :size="20" />
+ </template>
+ {{ t('spreed', 'Go to file') }}
+ </NcActionLink>
+ <NcActionSeparator v-if="showModerationOptions" />
+ <template v-if="showModerationOptions">
+ <NcActionButton :close-after-click="true"
+ icon="icon-rename"
+ @click="handleRenameConversation">
+ {{ t('spreed', 'Rename conversation') }}
+ </NcActionButton>
+ </template>
+ <NcActionButton :close-after-click="true"
+ @click="openConversationSettings">
+ <template #icon>
+ <Cog :size="20" />
+ </template>
+ {{ t('spreed', 'Conversation settings') }}
+ </NcActionButton>
+ </NcActions>
+</template>
+
+<script>
+import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
+import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'
+import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
+import { emit } from '@nextcloud/event-bus'
+import PromotedView from '../missingMaterialDesignIcons/PromotedView.vue'
+import Cog from 'vue-material-design-icons/Cog.vue'
+import DotsHorizontal from 'vue-material-design-icons/DotsHorizontal.vue'
+import GridView from '../missingMaterialDesignIcons/GridView.vue'
+import HandBackLeft from 'vue-material-design-icons/HandBackLeft.vue'
+import isInCall from '../../mixins/isInCall.js'
+import Blur from 'vue-material-design-icons/Blur.vue'
+import BlurOff from 'vue-material-design-icons/BlurOff.vue'
+import { callParticipantCollection } from '../../utils/webrtc/index.js'
+import { generateUrl } from '@nextcloud/router'
+import { CONVERSATION, PARTICIPANT } from '../../constants.js'
+import VideoIcon from 'vue-material-design-icons/Video.vue'
+import MicrophoneOff from 'vue-material-design-icons/MicrophoneOff.vue'
+
+export default {
+ name: 'TopBarMenu',
+
+ components: {
+ NcActions,
+ NcActionSeparator,
+ NcActionButton,
+ PromotedView,
+ Cog,
+ DotsHorizontal,
+ GridView,
+ HandBackLeft,
+ Blur,
+ BlurOff,
+ VideoIcon,
+ MicrophoneOff,
+ },
+
+ mixins: [
+ isInCall,
+ ],
+
+ props: {
+ /**
+ * The conversation token
+ */
+ token: {
+ type: String,
+ required: true,
+ },
+
+ /**
+ * The local media model
+ */
+ model: {
+ type: Object,
+ required: true,
+ },
+
+ showActions: {
+ type: Boolean,
+ default: true,
+ },
+
+ /**
+ * In the sidebar the conversation settings are hidden
+ */
+ isSidebar: {
+ type: Boolean,
+ default: false,
+ },
+ },
+
+ data() {
+ return {
+ boundaryElement: document.querySelector('.main-view'),
+ }
+ },
+
+ computed: {
+ conversation() {
+ return this.$store.getters.conversation(this.token) || this.$store.getters.dummyConversation
+ },
+
+ isFullscreen() {
+ return this.$store.getters.isFullscreen()
+ },
+
+ iconFullscreen() {
+ if (this.isInCall) {
+ return 'forced-white icon-fullscreen'
+ }
+ return 'icon-fullscreen'
+ },
+
+ labelFullscreen() {
+ if (this.isFullscreen) {
+ return t('spreed', 'Exit fullscreen (F)')
+ }
+ return t('spreed', 'Fullscreen (F)')
+ },
+
+ conversationHasSettings() {
+ return this.conversation.type === CONVERSATION.TYPE.GROUP
+ || this.conversation.type === CONVERSATION.TYPE.PUBLIC
+ },
+
+ showModerationOptions() {
+ return !this.isOneToOneConversation && this.canModerate
+ },
+
+ isFileConversation() {
+ return this.conversation.objectType === 'file' && this.conversation.objectId
+ },
+
+ linkToFile() {
+ if (this.isFileConversation) {
+ return window.location.protocol + '//' + window.location.host + generateUrl('/f/' + this.conversation.objectId)
+ } else {
+ return ''
+ }
+ },
+
+ isOneToOneConversation() {
+ return this.conversation.type === CONVERSATION.TYPE.ONE_TO_ONE
+ },
+
+ toggleVirtualBackgroundButtonLabel() {
+ if (!this.isVirtualBackgroundEnabled) {
+ return t('spreed', 'Blur background')
+ }
+ return t('spreed', 'Disable background blur')
+ },
+
+ container() {
+ return this.$store.getters.getMainContainerSelector()
+ },
+
+ changeViewText() {
+ if (this.isGrid) {
+ return t('spreed', 'Speaker view')
+ } else {
+ return t('spreed', 'Grid view')
+ }
+ },
+
+ isGrid() {
+ return this.$store.getters.isGrid
+ },
+
+ isVirtualBackgroundAvailable() {
+ return this.model.attributes.virtualBackgroundAvailable
+ },
+
+ isVirtualBackgroundEnabled() {
+ return this.model.attributes.virtualBackgroundEnabled
+ },
+
+ raiseHandButtonLabel() {
+ if (!this.model.attributes.raisedHand.state) {
+ if (this.disableKeyboardShortcuts) {
+ return t('spreed', 'Raise hand')
+ }
+ return t('spreed', 'Raise hand (R)')
+ }
+ if (this.disableKeyboardShortcuts) {
+ return t('spreed', 'Lower hand')
+ }
+ return t('spreed', 'Lower hand (R)')
+ },
+
+ disableKeyboardShortcuts() {
+ return OCP.Accessibility.disableKeyboardShortcuts()
+ },
+
+ participantType() {
+ return this.conversation.participantType
+ },
+
+ canFullModerate() {
+ return this.participantType === PARTICIPANT.TYPE.OWNER || this.participantType === PARTICIPANT.TYPE.MODERATOR
+ },
+
+ canModerate() {
+ return this.canFullModerate || this.participantType === PARTICIPANT.TYPE.GUEST_MODERATOR
+ },
+ },
+
+ methods: {
+ handleRenameConversation() {
+ this.$store.dispatch('isRenamingConversation', true)
+ this.$store.dispatch('showSidebar')
+ },
+ forceMuteOthers() {
+ callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
+ callParticipantModel.forceMute()
+ })
+ },
+
+ fullScreenChanged() {
+ this.$store.dispatch(
+ 'setIsFullscreen',
+ document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement
+ )
+ },
+
+ toggleFullscreen() {
+ if (this.isFullscreen) {
+ this.disableFullscreen()
+ this.$store.dispatch('setIsFullscreen', false)
+ } else {
+ this.enableFullscreen()
+ this.$store.dispatch('setIsFullscreen', true)
+ }
+ },
+
+ enableFullscreen() {
+ const fullscreenElem = document.getElementById('content-vue')
+
+ if (fullscreenElem.requestFullscreen) {
+ fullscreenElem.requestFullscreen()
+ } else if (fullscreenElem.webkitRequestFullscreen) {
+ fullscreenElem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)
+ } else if (fullscreenElem.mozRequestFullScreen) {
+ fullscreenElem.mozRequestFullScreen()
+ } else if (fullscreenElem.msRequestFullscreen) {
+ fullscreenElem.msRequestFullscreen()
+ }
+ },
+
+ disableFullscreen() {
+ if (document.exitFullscreen) {
+ document.exitFullscreen()
+ } else if (document.webkitExitFullscreen) {
+ document.webkitExitFullscreen()
+ } else if (document.mozCancelFullScreen) {
+ document.mozCancelFullScreen()
+ } else if (document.msExitFullscreen) {
+ document.msExitFullscreen()
+ }
+ },
+
+ toggleVirtualBackground() {
+ if (this.model.attributes.virtualBackgroundEnabled) {
+ this.model.disableVirtualBackground()
+ } else {
+ this.model.enableVirtualBackground()
+ }
+ },
+
+ changeView() {
+ this.$store.dispatch('setCallViewMode', { isGrid: !this.isGrid })
+ this.$store.dispatch('selectedVideoPeerId', null)
+ },
+
+ showSettings() {
+ emit('show-settings', {})
+ },
+
+ toggleHandRaised() {
+ const state = !this.model.attributes.raisedHand?.state
+ this.model.toggleHandRaised(state)
+ this.$store.dispatch(
+ 'setParticipantHandRaised',
+ {
+ sessionId: this.$store.getters.getSessionId(),
+ raisedHand: this.model.attributes.raisedHand,
+ }
+ )
+ },
+
+ openConversationSettings() {
+ emit('show-conversation-settings', { token: this.token })
+ },
+ },
+}
+</script>