Skip to content

Commit

Permalink
Merge pull request #13329 from nextcloud/fix/call-joining
Browse files Browse the repository at this point in the history
  • Loading branch information
DorraJaouad authored Nov 8, 2024
2 parents 3fa3cc0 + dba5c4b commit 4b0f62f
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 106 deletions.
7 changes: 7 additions & 0 deletions src/PublicShareSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<TopBar v-if="isInCall" is-in-call is-sidebar />
<CallView v-if="isInCall" :token="token" is-sidebar />
<CallButton v-if="!isInCall" class="call-button" />
<CallFailedDialog v-if="connectionFailed" :token="token" />
<ChatView is-sidebar />
<PollViewer />
<MediaSettings :recording-consent-given.sync="recordingConsentGiven" />
Expand All @@ -39,6 +40,7 @@ import { t } from '@nextcloud/l10n'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'

import CallFailedDialog from './components/CallView/CallFailedDialog.vue'
import CallView from './components/CallView/CallView.vue'
import ChatView from './components/ChatView.vue'
import MediaSettings from './components/MediaSettings/MediaSettings.vue'
Expand All @@ -63,6 +65,7 @@ export default {

components: {
CallButton,
CallFailedDialog,
CallView,
ChatView,
MediaSettings,
Expand Down Expand Up @@ -118,6 +121,10 @@ export default {
warnLeaving() {
return !this.isLeavingAfterSessionIssue && this.isInCall
},

connectionFailed() {
return this.$store.getters.connectionFailed(this.token)
},
},

created() {
Expand Down
70 changes: 70 additions & 0 deletions src/components/CallView/CallFailedDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup lang="ts">
import { computed } from 'vue'

import IconAlertOctagon from 'vue-material-design-icons/AlertOctagon.vue'

import { t } from '@nextcloud/l10n'

import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'

import { useStore } from '../../composables/useStore.js'

const store = useStore()

const props = defineProps({
token: {
type: String,
required: true,
},
})

const STATUS_ERRORS = {
400: t('spreed', 'Recording consent is required'),
403: t('spreed', 'This conversation is read-only'),
404: t('spreed', 'Conversation not found or not joined'),
412: t('spreed', "Lobby is still active and you're not a moderator"),
}
const connectionFailed = computed(() => store.getters.connectionFailed(props.token))
const connectionFailedDialogId = `connection-failed-${props.token}`
const message = computed(() => {
if (!connectionFailed.value) {
return ''
}

const statusCode = connectionFailed.value?.meta?.statuscode
if (STATUS_ERRORS[statusCode]) {
return STATUS_ERRORS[statusCode]
}
if (connectionFailed.value?.data?.error) {
return connectionFailed.value.data.error
}

return t('spreed', 'Please try to reload the page')
})

/**
*
*/
function clearConnectionFailedError() {
store.dispatch('clearConnectionFailed', props.token)
}

</script>

<template>
<NcModal :label-id="connectionFailedDialogId"
@close="clearConnectionFailedError">
<NcEmptyContent :name="t('spreed', 'Connection failed')"
:description="message">
<template #icon>
<IconAlertOctagon />
</template>
</NcEmptyContent>
</NcModal>
</template>
42 changes: 2 additions & 40 deletions src/components/CallView/shared/EmptyCallView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
<p v-if="message" class="emptycontent-additional">
{{ message }}
</p>
<p v-if="helper" class="emptycontent-additional">
{{ helper }}
</p>
<NcButton v-if="showLink"
type="primary"
@click.stop="handleCopyLink">
Expand All @@ -30,7 +27,6 @@

<script>
import IconAccountMultiple from 'vue-material-design-icons/AccountMultiple.vue'
import IconAlertOctagon from 'vue-material-design-icons/AlertOctagon.vue'
import IconLinkVariant from 'vue-material-design-icons/LinkVariant.vue'
import IconPhone from 'vue-material-design-icons/Phone.vue'

Expand All @@ -42,24 +38,16 @@ import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import { CONVERSATION, PARTICIPANT } from '../../../constants.js'
import { copyConversationLinkToClipboard } from '../../../utils/handleUrl.ts'

const STATUS_ERRORS = {
400: t('spreed', 'Recording consent is required'),
403: t('spreed', 'This conversation is read-only'),
404: t('spreed', 'Conversation not found or not joined'),
412: t('spreed', "Lobby is still active and you're not a moderator"),
}

export default {

name: 'EmptyCallView',

components: {
NcButton,
NcLoadingIcon,
IconAccountMultiple,
IconAlertOctagon,
IconLinkVariant,
IconPhone,
NcLoadingIcon,
},

props: {
Expand All @@ -80,7 +68,6 @@ export default {
},

computed: {

token() {
return this.$store.getters.getToken()
},
Expand All @@ -89,10 +76,6 @@ export default {
return this.$store.getters.isConnecting(this.token)
},

connectionFailed() {
return this.$store.getters.connectionFailed(this.token)
},

conversation() {
return this.$store.getters.conversation(this.token)
},
Expand Down Expand Up @@ -138,9 +121,7 @@ export default {
},

emptyCallViewIcon() {
if (this.connectionFailed) {
return IconAlertOctagon
} else if (this.isConnecting) {
if (this.isConnecting) {
return NcLoadingIcon
} else if (this.isPhoneConversation) {
return IconPhone
Expand All @@ -150,9 +131,6 @@ export default {
},

title() {
if (this.connectionFailed) {
return t('spreed', 'Connection failed')
}
if (this.isConnecting) {
return t('spreed', 'Connecting …')
}
Expand All @@ -165,23 +143,7 @@ export default {
return t('spreed', 'Waiting for others to join the call …')
},

helper() {
return this.connectionFailed ? t('spreed', 'Please try to reload the page') : ''
},

message() {
if (this.connectionFailed) {
const statusCode = this.connectionFailed?.meta?.statuscode
if (STATUS_ERRORS[statusCode]) {
return STATUS_ERRORS[statusCode]
}
if (this.connectionFailed?.data?.error) {
return this.connectionFailed.data.error
}

return t('spreed', 'Something went wrong')
}

if (this.isConnecting) {
return ''
}
Expand Down
25 changes: 20 additions & 5 deletions src/components/TopBar/CallButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,29 @@
id="call_button"
:title="startCallTitle"
:aria-label="startCallLabel"
:disabled="startCallButtonDisabled || loading"
:disabled="startCallButtonDisabled || loading || isJoiningCall"
:type="startCallButtonType"
@click="handleClick">
<template #icon>
<IconPhoneDial v-if="isPhoneRoom" :size="20" />
<NcLoadingIcon v-if="isJoiningCall || loading" :size="20" />
<IconPhoneDial v-else-if="isPhoneRoom" :size="20" />
<IconPhoneOutline v-else-if="silentCall" :size="20" />
<IconPhone v-else :size="20" />
</template>
<template v-if="showButtonText" #default>
{{ startCallLabel }}
</template>
</NcButton>

<NcButton v-else-if="showLeaveCallButton && canEndForAll && isPhoneRoom"
id="call_button"
:aria-label="endCallLabel"
type="error"
:disabled="loading"
@click="leaveCall(true)">
<template #icon>
<IconPhoneHangup :size="20" /> <!-- here -->
<NcLoadingIcon v-if="loading" :size="20" />
<IconPhoneHangup v-else :size="20" /> <!-- here -->
</template>
<template v-if="showButtonText" #default>
{{ endCallLabel }}
Expand All @@ -41,7 +44,8 @@
:disabled="loading"
@click="leaveCall(false)">
<template #icon>
<IconPhoneHangup :size="20" />
<NcLoadingIcon v-if="loading" :size="20" />
<IconPhoneHangup v-else :size="20" />
</template>
<template v-if="showButtonText" #default>
{{ leaveCallLabel }}
Expand All @@ -54,7 +58,8 @@
force-name
:type="isScreensharing ? 'tertiary' : 'error'">
<template #icon>
<IconPhoneHangup v-if="!isBreakoutRoom" :size="20" />
<NcLoadingIcon v-if="loading" :size="20" />
<IconPhoneHangup v-else-if="!isBreakoutRoom" :size="20" />
<IconArrowLeft v-else :size="20" />
</template>
<NcActionButton v-if="isBreakoutRoom"
Expand Down Expand Up @@ -96,6 +101,7 @@ import { t } from '@nextcloud/l10n'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import { useIsMobile } from '@nextcloud/vue/dist/Composables/useIsMobile.js'

import { useIsInCall } from '../../composables/useIsInCall.js'
Expand Down Expand Up @@ -124,6 +130,7 @@ export default {
IconPhoneHangup,
IconPhoneOff,
IconPhoneOutline,
NcLoadingIcon,
},

props: {
Expand Down Expand Up @@ -268,6 +275,10 @@ export default {
return t('spreed', 'Join call')
}

if (this.isJoiningCall) {
return t('spreed', 'Connecting …')
}

return this.silentCall ? t('spreed', 'Start call silently') : t('spreed', 'Start call')
},

Expand Down Expand Up @@ -334,6 +345,10 @@ export default {
isInLobby() {
return this.$store.getters.isInLobby
},

isJoiningCall() {
return this.$store.getters.isJoiningCall(this.token)
},
},

watch: {
Expand Down
8 changes: 2 additions & 6 deletions src/services/callsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,10 @@ import {
* @param {boolean} silent Whether the call should trigger a notifications and
* sound for other participants or not
* @param {boolean} recordingConsent Whether the participant gave their consent to be recorded
* @return {number} The actual flags based on the available media
* @return {Promise<number>} The actual flags based on the available media
*/
const joinCall = async function(token, flags, silent, recordingConsent) {
try {
return await signalingJoinCall(token, flags, silent, recordingConsent)
} catch (error) {
console.debug('Error while joining call: ', error)
}
return signalingJoinCall(token, flags, silent, recordingConsent)
}

/**
Expand Down
Loading

0 comments on commit 4b0f62f

Please sign in to comment.