Merge pull request #9731 from nextcloud/fix/9725/refactor-top-bar

Fix displaying 'Screensharing' button after reject and refactor `TopBar` controls for 'Raise hand' and 'Screensharing'
This commit is contained in:
Maksim Sukharev 2023-06-12 14:26:02 +02:00 committed by GitHub
commit 31e5295c66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 232 additions and 254 deletions

View file

@ -82,7 +82,7 @@
:local-call-participant-model="localCallParticipantModel" />
<!-- Local media controls -->
<LocalMediaControls v-if="isInCall"
<TopBarMediaControls v-if="isInCall"
class="local-media-controls dark-hover"
:token="token"
:model="localMediaModel"
@ -156,11 +156,11 @@ import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
import richEditor from '@nextcloud/vue/dist/Mixins/richEditor.js'
import BreakoutRoomsEditor from '../BreakoutRoomsEditor/BreakoutRoomsEditor.vue'
import LocalMediaControls from '../CallView/shared/LocalMediaControls.vue'
import ConversationIcon from '../ConversationIcon.vue'
import CallButton from './CallButton.vue'
import CallTime from './CallTime.vue'
import ReactionMenu from './ReactionMenu.vue'
import TopBarMediaControls from './TopBarMediaControls.vue'
import TopBarMenu from './TopBarMenu.vue'
import { CONVERSATION } from '../../constants.js'
@ -182,7 +182,7 @@ export default {
CallButton,
CallTime,
ConversationIcon,
LocalMediaControls,
TopBarMediaControls,
NcButton,
NcCounterBubble,
TopBarMenu,

View file

@ -19,118 +19,100 @@
-->
<template>
<div v-shortkey.push="disableKeyboardShortcuts ? null : ['space']"
class="buttons-bar"
@shortkey="handleShortkey">
<div class="buttons-bar">
<div class="network-connection-state">
<NcPopover v-if="qualityWarningTooltip"
:boundary="boundaryElement"
:aria-label="qualityWarningAriaLabel"
trigger="hover"
:auto-hide="false"
:shown="showQualityWarningTooltip">
<template #trigger>
<NcButton id="quality_warning_button"
type="tertiary-no-background"
class="trigger"
:aria-label="qualityWarningAriaLabel"
@click="mouseover = !mouseover">
<template #icon>
<NetworkStrength2Alert fill-color="#e9322d" :size="20" />
</template>
<div class="network-connection-state">
<NcPopover v-if="qualityWarningTooltip"
:boundary="boundaryElement"
:aria-label="qualityWarningAriaLabel"
trigger="hover"
:auto-hide="false"
:shown="showQualityWarningTooltip">
<template #trigger>
<NcButton id="quality_warning_button"
type="tertiary-no-background"
class="trigger"
:aria-label="qualityWarningAriaLabel"
@click="mouseover = !mouseover">
<template #icon>
<NetworkStrength2Alert fill-color="#e9322d" :size="20" />
</template>
</NcButton>
</template>
<div class="hint">
<span>{{ qualityWarningTooltip.content }}</span>
<div class="hint__actions">
<NcButton v-if="qualityWarningTooltip.action"
type="primary"
class="hint__button"
@click="executeQualityWarningTooltipAction">
{{ qualityWarningTooltip.actionLabel }}
</NcButton>
<NcButton v-if="!isQualityWarningTooltipDismissed"
type="tertiary"
class="hint__button"
@click="dismissQualityWarningTooltip">
{{ t('spreed', 'Dismiss') }}
</NcButton>
</template>
<div class="hint">
<span>{{ qualityWarningTooltip.content }}</span>
<div class="hint__actions">
<NcButton v-if="qualityWarningTooltip.action"
type="primary"
class="hint__button"
@click="executeQualityWarningTooltipAction">
{{ qualityWarningTooltip.actionLabel }}
</NcButton>
<NcButton v-if="!isQualityWarningTooltipDismissed"
type="tertiary"
class="hint__button"
@click="dismissQualityWarningTooltip">
{{ t('spreed', 'Dismiss') }}
</NcButton>
</div>
</div>
</NcPopover>
</div>
</div>
</NcPopover>
</div>
<LocalAudioControlButton :conversation="conversation" :model="model" color="#ffffff" />
<LocalAudioControlButton :conversation="conversation" :model="model" color="#ffffff" />
<LocalVideoControlButton :conversation="conversation" :model="model" color="#ffffff" />
<LocalVideoControlButton :conversation="conversation" :model="model" color="#ffffff" />
<NcButton v-if="isVirtualBackgroundAvailable && !showActions"
v-tooltip="toggleVirtualBackgroundButtonLabel"
type="tertiary-no-background"
:aria-label="toggleVirtualBackgroundButtonLabel"
:class="blurButtonClass"
@click.stop="toggleVirtualBackground">
<NcButton v-if="isVirtualBackgroundAvailable && !showActions"
v-tooltip="toggleVirtualBackgroundButtonLabel"
type="tertiary-no-background"
:aria-label="toggleVirtualBackgroundButtonLabel"
:class="blurButtonClass"
@click.stop="toggleVirtualBackground">
<template #icon>
<Blur v-if="isVirtualBackgroundEnabled" :size="20" fill-color="#ffffff" />
<BlurOff v-else :size="20" fill-color="#ffffff" />
</template>
</NcButton>
<NcActions v-if="!screenSharingButtonHidden"
id="screensharing-button"
v-tooltip="screenSharingButtonTooltip"
:aria-label="screenSharingButtonAriaLabel"
:class="screenSharingButtonClass"
class="app-navigation-entry-utils-menu-button"
:boundaries-element="boundaryElement"
:container="container"
:open.sync="screenSharingMenuOpen">
<!-- Actions button icon -->
<template #icon>
<CancelPresentation v-if="model.attributes.localScreen" :size="20" fill-color="#ffffff" />
<PresentToAll v-else :size="20" fill-color="#ffffff" />
</template>
<!-- /Actions button icon -->
<!-- Actions -->
<NcActionButton v-if="!screenSharingMenuOpen"
@click.stop="toggleScreenSharingMenu">
<template #icon>
<Blur v-if="isVirtualBackgroundEnabled" :size="20" fill-color="#ffffff" />
<BlurOff v-else :size="20" fill-color="#ffffff" />
<PresentToAll :size="20" fill-color="#ffffff" />
</template>
</NcButton>
<NcActions v-if="!screenSharingButtonHidden"
id="screensharing-button"
v-tooltip="screenSharingButtonTooltip"
:aria-label="screenSharingButtonAriaLabel"
:class="screenSharingButtonClass"
class="app-navigation-entry-utils-menu-button"
:boundaries-element="boundaryElement"
:container="container"
:open="screenSharingMenuOpen"
@update:open="screenSharingMenuOpen = true"
@update:close="screenSharingMenuOpen = false">
<!-- Actions button icon -->
<template #icon>
<CancelPresentation v-if="model.attributes.localScreen" :size="20" fill-color="#ffffff" />
<PresentToAll v-else :size="20" fill-color="#ffffff" />
</template>
<!-- /Actions button icon -->
<!-- Actions -->
<NcActionButton v-if="!screenSharingMenuOpen"
@click.stop="toggleScreenSharingMenu">
<template #icon>
<PresentToAll :size="20" fill-color="#ffffff" />
</template>
{{ screenSharingButtonTooltip }}
</NcActionButton>
<NcActionButton v-if="model.attributes.localScreen"
@click="showScreen">
{{ screenSharingButtonTooltip }}
</NcActionButton>
<template v-if="model.attributes.localScreen">
<NcActionButton close-after-click @click="showScreen">
<template #icon>
<Monitor :size="20" />
</template>
{{ t('spreed', 'Show your screen') }}
</NcActionButton>
<NcActionButton v-if="model.attributes.localScreen"
@click="stopScreen">
<NcActionButton close-after-click @click="stopScreen">
<template #icon>
<CancelPresentation :size="20" />
</template>
{{ t('spreed', 'Stop screensharing') }}
</NcActionButton>
</NcActions>
<NcButton v-shortkey.once="disableKeyboardShortcuts ? null : ['r']"
v-tooltip="lowerHandAriaLabel"
:aria-label="lowerHandAriaLabel"
type="tertiary-no-background"
class="lower-hand"
:class="model.attributes.raisedHand.state ? '' : 'hidden-visually'"
:tabindex="model.attributes.raisedHand.state ? 0 : -1"
@shortkey="toggleHandRaised"
@click.stop="toggleHandRaised">
<template #icon>
<!-- The following icon is much bigger than all the others
so we reduce its size -->
<HandBackLeft :size="18" fill-color="#ffffff" />
</template>
</NcButton>
</div>
</template>
</NcActions>
</div>
</template>
@ -139,7 +121,6 @@ import escapeHtml from 'escape-html'
import Blur from 'vue-material-design-icons/Blur.vue'
import BlurOff from 'vue-material-design-icons/BlurOff.vue'
import HandBackLeft from 'vue-material-design-icons/HandBackLeft.vue'
import Monitor from 'vue-material-design-icons/Monitor.vue'
import NetworkStrength2Alert from 'vue-material-design-icons/NetworkStrength2Alert.vue'
@ -152,20 +133,20 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcPopover from '@nextcloud/vue/dist/Components/NcPopover.js'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
import CancelPresentation from '../../missingMaterialDesignIcons/CancelPresentation.vue'
import PresentToAll from '../../missingMaterialDesignIcons/PresentToAll.vue'
import LocalAudioControlButton from './LocalAudioControlButton.vue'
import LocalVideoControlButton from './LocalVideoControlButton.vue'
import LocalAudioControlButton from '../CallView/shared/LocalAudioControlButton.vue'
import LocalVideoControlButton from '../CallView/shared/LocalVideoControlButton.vue'
import CancelPresentation from '../missingMaterialDesignIcons/CancelPresentation.vue'
import PresentToAll from '../missingMaterialDesignIcons/PresentToAll.vue'
import { useIsInCall } from '../../../composables/useIsInCall.js'
import { PARTICIPANT } from '../../../constants.js'
import { CONNECTION_QUALITY } from '../../../utils/webrtc/analyzers/PeerConnectionAnalyzer.js'
import { callAnalyzer } from '../../../utils/webrtc/index.js'
import SpeakingWhileMutedWarner from '../../../utils/webrtc/SpeakingWhileMutedWarner.js'
import { useIsInCall } from '../../composables/useIsInCall.js'
import { PARTICIPANT } from '../../constants.js'
import { CONNECTION_QUALITY } from '../../utils/webrtc/analyzers/PeerConnectionAnalyzer.js'
import { callAnalyzer } from '../../utils/webrtc/index.js'
import SpeakingWhileMutedWarner from '../../utils/webrtc/SpeakingWhileMutedWarner.js'
export default {
name: 'LocalMediaControls',
name: 'TopBarMediaControls',
directives: {
tooltip: Tooltip,
@ -176,7 +157,6 @@ export default {
Blur,
BlurOff,
CancelPresentation,
HandBackLeft,
Monitor,
NcActions,
NcActionButton,
@ -258,12 +238,6 @@ export default {
return this.conversation.permissions & PARTICIPANT.PERMISSIONS.PUBLISH_SCREEN
},
lowerHandAriaLabel() {
return this.disableKeyboardShortcuts
? t('spreed', 'Lower hand')
: t('spreed', 'Lower hand (R)')
},
blurButtonClass() {
return {
'blur-disabled': this.isVirtualBackgroundEnabled,
@ -517,37 +491,19 @@ export default {
return
}
if (this.model.attributes.localScreen) {
this.screenSharingMenuOpen = !this.screenSharingMenuOpen
} else {
if (!this.model.attributes.localScreen) {
this.startShareScreen()
}
},
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,
}
)
},
showScreen() {
if (this.model.attributes.localScreen) {
emit('switch-screen-to-id', this.localCallParticipantModel.attributes.peerId)
}
this.screenSharingMenuOpen = false
},
stopScreen() {
this.model.stopSharingScreen()
this.screenSharingMenuOpen = false
},
startShareScreen(mode) {
@ -614,22 +570,13 @@ export default {
</script>
<style lang="scss" scoped>
@import '../../../assets/variables';
@import '../../assets/variables';
.buttons-bar {
display: flex;
align-items: center;
}
.buttons-bar button.lower-hand.hidden-visually {
position: absolute;
left: -10000px;
top: -10000px;
width: 1px;
height: 1px;
overflow: hidden;
}
.buttons-bar #screensharing-menu button {
width: 100%;
height: auto;

View file

@ -20,130 +20,146 @@
-->
<template>
<NcActions v-if="!isSidebar"
v-shortkey.once="disableKeyboardShortcuts ? null : ['f']"
v-tooltip="t('spreed', 'Conversation actions')"
:aria-label="t('spreed', 'Conversation actions')"
:container="container"
@shortkey.native="toggleFullscreen">
<!-- Menu icon: white 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">
<div class="top-bar__wrapper">
<NcButton v-show="isInCall && isHandRaised"
v-shortkey.once="disableKeyboardShortcuts ? null : ['r']"
v-tooltip="raiseHandButtonLabel"
:aria-label="raiseHandButtonLabel"
type="tertiary-no-background"
@shortkey="toggleHandRaised"
@click.stop="toggleHandRaised">
<template #icon>
<!-- The following icon is much bigger than all the others
so we reduce its size -->
<template #icon>
<HandBackLeft :size="16" />
<HandBackLeft :size="18" fill-color="#ffffff" />
</template>
</NcButton>
<NcActions v-if="!isSidebar"
v-shortkey.once="disableKeyboardShortcuts ? null : ['f']"
v-tooltip="t('spreed', 'Conversation actions')"
:aria-label="t('spreed', 'Conversation actions')"
:container="container"
@shortkey.native="toggleFullscreen">
<!-- Menu icon: white 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
@click="toggleHandRaised">
<!-- The following icon is much bigger than all the others
so we reduce its size -->
<template #icon>
<HandBackLeft :size="16" />
</template>
{{ raiseHandButtonLabel }}
</NcActionButton>
<!-- Mute others -->
<template v-if="!isOneToOneConversation && canFullModerate">
<NcActionButton close-after-click
@click="forceMuteOthers">
<template #icon>
<MicrophoneOff :size="20" />
</template>
{{ t('spreed', 'Mute others') }}
</NcActionButton>
</template>
{{ raiseHandButtonLabel }}
<!-- Device settings -->
<NcActionButton close-after-click
@click="showMediaSettings">
<template #icon>
<VideoIcon :size="20" />
</template>
{{ t('spreed', 'Media settings') }}
</NcActionButton>
<NcActionSeparator />
</template>
<!-- Call layout switcher -->
<NcActionButton v-if="showActions && isInCall"
close-after-click
@click="changeView">
<template #icon>
<GridView v-if="!isGrid"
:size="20" />
<PromotedView v-else
:size="20" />
</template>
{{ changeViewText }}
</NcActionButton>
<!-- Mute others -->
<template v-if="!isOneToOneConversation && canFullModerate">
<NcActionButton :close-after-click="true"
@click="forceMuteOthers">
<!-- Fullscreen -->
<NcActionButton :aria-label="t('spreed', 'Toggle full screen')"
close-after-click
@click="toggleFullscreen">
<template #icon>
<Fullscreen v-if="!isFullscreen" :size="20" />
<FullscreenExit v-else :size="20" />
</template>
{{ labelFullscreen }}
</NcActionButton>
<!-- Go to file -->
<NcActionLink v-if="isFileConversation"
:href="linkToFile">
<template #icon>
<File :size="20" />
</template>
{{ t('spreed', 'Go to file') }}
</NcActionLink>
<!-- Call recording -->
<template v-if="canModerateRecording">
<NcActionButton v-if="!isRecording && !isStartingRecording && isInCall"
close-after-click
@click="startRecording">
<template #icon>
<MicrophoneOff :size="20" />
<RecordCircle :size="20" />
</template>
{{ t('spreed', 'Mute others') }}
{{ t('spreed', 'Start recording') }}
</NcActionButton>
<NcActionButton v-else-if="isStartingRecording && isInCall"
close-after-click
@click="stopRecording">
<template #icon>
<NcLoadingIcon :size="20" />
</template>
{{ t('spreed', 'Cancel recording start') }}
</NcActionButton>
<NcActionButton v-else-if="isRecording && isInCall"
close-after-click
@click="stopRecording">
<template #icon>
<StopIcon :size="20" />
</template>
{{ t('spreed', 'Stop recording') }}
</NcActionButton>
</template>
<!-- Device settings -->
<NcActionButton :close-after-click="true"
@click="showMediaSettings">
<!-- Breakout rooms -->
<NcActionButton v-if="canConfigureBreakoutRooms"
close-after-click
@click="$emit('open-breakout-rooms-editor')">
<template #icon>
<VideoIcon :size="20" />
<DotsCircle :size="20" />
</template>
{{ t('spreed', 'Media settings') }}
{{ t('spreed', 'Set up breakout rooms') }}
</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>
<!-- Fullscreen -->
<NcActionButton :aria-label="t('spreed', 'Toggle full screen')"
:close-after-click="true"
@click="toggleFullscreen">
<template #icon>
<Fullscreen v-if="!isFullscreen" :size="20" />
<FullscreenExit v-else :size="20" />
</template>
{{ labelFullscreen }}
</NcActionButton>
<!-- Go to file -->
<NcActionLink v-if="isFileConversation"
:href="linkToFile">
<template #icon>
<File :size="20" />
</template>
{{ t('spreed', 'Go to file') }}
</NcActionLink>
<!-- Call recording -->
<template v-if="canModerateRecording">
<NcActionButton v-if="!isRecording && !isStartingRecording && isInCall"
:close-after-click="true"
@click="startRecording">
<!-- Conversation settings -->
<NcActionButton close-after-click
@click="openConversationSettings">
<template #icon>
<RecordCircle :size="20" />
<Cog :size="20" />
</template>
{{ t('spreed', 'Start recording') }}
{{ t('spreed', 'Conversation settings') }}
</NcActionButton>
<NcActionButton v-else-if="isStartingRecording && isInCall"
:close-after-click="true"
@click="stopRecording">
<template #icon>
<NcLoadingIcon :size="20" />
</template>
{{ t('spreed', 'Cancel recording start') }}
</NcActionButton>
<NcActionButton v-else-if="isRecording && isInCall"
:close-after-click="true"
@click="stopRecording">
<template #icon>
<StopIcon :size="20" />
</template>
{{ t('spreed', 'Stop recording') }}
</NcActionButton>
</template>
<!-- Breakout rooms -->
<NcActionButton v-if="canConfigureBreakoutRooms"
:close-after-click="true"
@click="$emit('open-breakout-rooms-editor')">
<template #icon>
<DotsCircle :size="20" />
</template>
{{ t('spreed', 'Set up breakout rooms') }}
</NcActionButton>
<!-- Conversation settings -->
<NcActionButton :close-after-click="true"
@click="openConversationSettings">
<template #icon>
<Cog :size="20" />
</template>
{{ t('spreed', 'Conversation settings') }}
</NcActionButton>
</NcActions>
</NcActions>
</div>
</template>
<script>
@ -165,6 +181,7 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import GridView from '../missingMaterialDesignIcons/GridView.vue'
@ -179,6 +196,7 @@ export default {
name: 'TopBarMenu',
components: {
NcButton,
NcActions,
NcActionSeparator,
NcActionLink,
@ -299,8 +317,12 @@ export default {
return this.model.attributes.virtualBackgroundEnabled
},
isHandRaised() {
return this.model.attributes.raisedHand?.state === true
},
raiseHandButtonLabel() {
if (!this.model.attributes.raisedHand.state) {
if (!this.isHandRaised) {
if (this.disableKeyboardShortcuts) {
return t('spreed', 'Raise hand')
}
@ -429,8 +451,8 @@ export default {
},
toggleHandRaised() {
const state = !this.model.attributes.raisedHand?.state
this.model.toggleHandRaised(state)
const newState = !this.isHandRaised
this.model.toggleHandRaised(newState)
this.$store.dispatch(
'setParticipantHandRaised',
{
@ -466,3 +488,12 @@ export default {
},
}
</script>
<style lang="scss" scoped>
@import '../../assets/variables';
.top-bar {
&__wrapper {
display: flex;
}
}
</style>