feat(forceCallView): add the UI

Signed-off-by: DorraJaouad <dorra.jaoued7@gmail.com>
This commit is contained in:
DorraJaouad
2024-10-29 00:03:05 +01:00
parent 26b1d62688
commit fce900a8e6
3 changed files with 159 additions and 2 deletions

View File

@ -265,7 +265,19 @@ export default {
return this.callViewStore.isViewerOverlay
},
forcedCallViewMode() {
return this.localCallParticipantModel.attributes.forcedCallViewMode
},
isGrid() {
if (this.forcedCallViewMode === 'grid' && !this.$store.getters.isModerator) {
return true
}
if (this.forcedCallViewMode === 'speaker' && !this.$store.getters.isModerator) {
return false
}
return this.callViewStore.isGrid && !this.isSidebar
},
@ -487,6 +499,7 @@ export default {
mounted() {
this.debounceFetchPeers = debounce(this.fetchPeers, 1500)
EventBus.on('refresh-peer-list', this.debounceFetchPeers)
EventBus.on('force-call-view-mode', this.forceCallViewMode)
callParticipantCollection.on('remove', this._lowerHandWhenParticipantLeaves)
@ -498,6 +511,7 @@ export default {
this.debounceFetchPeers.clear?.()
this.callViewStore.setIsEmptyCallView(true)
EventBus.off('refresh-peer-list', this.debounceFetchPeers)
EventBus.off('force-call-view-mode', this.forceCallViewMode)
callParticipantCollection.off('remove', this._lowerHandWhenParticipantLeaves)
@ -797,6 +811,10 @@ export default {
}
},
forceCallViewMode(mode) {
this.localCallParticipantModel.forceCallViewMode(mode)
},
},
}
</script>

View File

@ -0,0 +1,104 @@
<template>
<NcModal v-if="showCallModerationDialog"
size="small"
:name="t('spreed', 'Moderate the call')"
@close="closeModal">
<div class="call_moderation">
<h2 class="call_moderation--header nc-dialog-alike-header">
{{ t('spreed', 'Moderate the call') }}
</h2>
<p>
{{ t('spreed', 'Force the view mode for all participants') }}
</p>
<div class="call_view_mode">
<NcCheckboxRadioSwitch button-variant
:checked.sync="forcedCallView"
value="grid"
name="grid_view_radio"
type="radio"
button-variant-grouped="vertical">
{{ t('spreed', 'Force Grid view') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch button-variant
:checked.sync="forcedCallView"
value="speaker"
name="speaker_view_radio"
type="radio"
button-variant-grouped="vertical">
{{ t('spreed', 'Force Speaker view') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch button-variant
:checked.sync="forcedCallView"
value="none"
name="none_view_radio"
type="radio"
button-variant-grouped="vertical">
{{ t('spreed', 'None') }}
</NcCheckboxRadioSwitch>
</div>
</div>
</NcModal>
</template>
<script>
import { t } from '@nextcloud/l10n'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import { EventBus } from '../../services/EventBus.js'
import { localCallParticipantModel } from '../../utils/webrtc/index.js'
export default {
name: 'CallModerationDialog',
components: {
NcModal,
NcCheckboxRadioSwitch
},
props: {
showCallModerationDialog: {
type: Boolean,
default: false
}
},
emits: ['update:showCallModerationDialog'],
setup() {
return {
localCallParticipantModel,
}
},
data() {
return {
forcedCallView: this.localCallParticipantModel.attributes.forcedCallView ?? 'none',
}
},
watch: {
forcedCallView(value) {
EventBus.emit('force-call-view-mode', value)
},
},
methods: {
t,
closeModal() {
this.$emit('update:showCallModerationDialog', false)
}
}
}
</script>
<style lang="scss" scoped>
.call_moderation {
padding: calc(var(--default-grid-baseline) * 5);
.call_view_mode {
width: fit-content;
}
}
</style>

View File

@ -62,6 +62,7 @@
<!-- Call layout switcher -->
<NcActionButton v-if="showCallLayoutSwitch"
close-after-click
:disabled="isCallViewChangeDisabled"
@click="changeView">
<template #icon>
<GridView v-if="!isGrid"
@ -71,6 +72,14 @@
</template>
{{ changeViewText }}
</NcActionButton>
<NcActionButton v-if="canModerate"
close-after-click
@click="showCallModerationDialog = true">
<template #icon>
<IconAccountGroup :size="20" />
</template>
{{ t('spreed', 'Moderate the call') }}
</NcActionButton>
</template>
<!-- Fullscreen -->
@ -148,10 +157,13 @@
{{ t('spreed', 'Download attendance list') }}
</NcActionLink>
</NcActions>
<CallModerationDialog :show-call-moderation-dialog.sync="showCallModerationDialog" />
</div>
</template>
<script>
import IconAccountGroup from 'vue-material-design-icons/AccountGroup.vue'
import Cog from 'vue-material-design-icons/Cog.vue'
import DotsCircle from 'vue-material-design-icons/DotsCircle.vue'
import DotsHorizontal from 'vue-material-design-icons/DotsHorizontal.vue'
@ -180,6 +192,7 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import { useHotKey } from '@nextcloud/vue/dist/Composables/useHotKey.js'
import CallModerationDialog from './CallModerationDialog.vue'
import TransitionExpand from '../MediaSettings/TransitionExpand.vue'
import {
@ -193,7 +206,7 @@ import { getTalkConfig, hasTalkFeature } from '../../services/CapabilitiesManage
import { useBreakoutRoomsStore } from '../../stores/breakoutRooms.ts'
import { useCallViewStore } from '../../stores/callView.js'
import { generateAbsoluteUrl } from '../../utils/handleUrl.ts'
import { callParticipantCollection } from '../../utils/webrtc/index.js'
import { callParticipantCollection, localCallParticipantModel } from '../../utils/webrtc/index.js'
const AUTO_LOWER_HAND_THRESHOLD = 3000
const disableKeyboardShortcuts = OCP.Accessibility.disableKeyboardShortcuts()
@ -202,6 +215,7 @@ export default {
name: 'TopBarMenu',
components: {
CallModerationDialog,
TransitionExpand,
NcActionButton,
NcActionLink,
@ -218,6 +232,7 @@ export default {
FullscreenExit,
GridView,
HandBackLeft,
IconAccountGroup,
IconDownload,
MicrophoneOff,
PromotedView,
@ -274,6 +289,8 @@ export default {
lowerHandTimeout: null,
speakingTimestamp: null,
lowerHandDelay: AUTO_LOWER_HAND_THRESHOLD,
showCallModerationDialog: false,
localCallParticipantModel,
}
},
@ -309,8 +326,26 @@ export default {
: t('spreed', 'Grid view')
},
forcedCallViewMode() {
return this.localCallParticipantModel.attributes.forcedCallViewMode
},
isCallViewChangeDisabled() {
return !(this.forcedCallViewMode === 'none')
&& !(this.forcedCallViewMode === '')
&& !this.canModerate
},
isGrid() {
return this.callViewStore.isGrid
if (this.forcedCallViewMode === 'grid' && !this.canModerate) {
return true
}
if (this.forcedCallViewMode === 'speaker' && !this.canModerate) {
return false
}
return this.callViewStore.isGrid && !this.isSidebar
},
isVirtualBackgroundAvailable() {