-
Notifications
You must be signed in to change notification settings - Fork 429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(Call): introduce intermediary phase before joining call #13329
base: main
Are you sure you want to change the base?
Changes from all commits
78a6245
7658d25
1228dff
08d118b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 store from '../../store/index.js' | ||
|
||
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 userId = computed(() => store.getters.userId) | ||
const connectionFailed = computed(() => store.getters.connectionFailed(props.token)) | ||
const connectionFailedDialgId = `connection-failed-${userId.value}` | ||
const message = computed(() => { | ||
if (connectionFailed.value) { | ||
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') | ||
} else { | ||
return '' | ||
} | ||
}) | ||
|
||
/** | ||
* | ||
*/ | ||
function clearConnectionFailedError() { | ||
store.dispatch('clearConnectionFailed', props.token) | ||
} | ||
|
||
</script> | ||
|
||
<template> | ||
<NcModal class="connection-failed__modal" | ||
:label-id="connectionFailedDialgId" | ||
@close="clearConnectionFailedError"> | ||
<NcEmptyContent :name="t('spreed', 'Connection failed')" | ||
:description="message"> | ||
<template #icon> | ||
<IconAlertOctagon /> | ||
</template> | ||
</NcEmptyContent> | ||
</NcModal> | ||
</template> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ const joinCall = async function(token, flags, silent, recordingConsent) { | |
return await signalingJoinCall(token, flags, silent, recordingConsent) | ||
} catch (error) { | ||
console.debug('Error while joining call: ', error) | ||
throw error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe remove try-catch block here, since it's not needed? |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -321,27 +321,29 @@ const mutations = { | |
if (state.inCall[token] && state.inCall[token][sessionId]) { | ||
Vue.delete(state.inCall[token], sessionId) | ||
} | ||
|
||
if (state.connecting[token] && state.connecting[token][sessionId]) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can keep this resetting (in case it survives somehow). Maybe via |
||
Vue.delete(state.connecting[token], sessionId) | ||
} | ||
} else { | ||
if (!state.inCall[token]) { | ||
Vue.set(state.inCall, token, {}) | ||
} | ||
Vue.set(state.inCall[token], sessionId, flags) | ||
|
||
if (!state.connecting[token]) { | ||
Vue.set(state.connecting, token, {}) | ||
} | ||
Vue.set(state.connecting[token], sessionId, flags) | ||
} | ||
}, | ||
|
||
connectionFailed(state, { token, payload }) { | ||
Vue.set(state.connectionFailed, token, payload) | ||
}, | ||
|
||
clearConnectionFailed(state, token) { | ||
Vue.delete(state.connectionFailed, token) | ||
}, | ||
|
||
connecting(state, { token, sessionId, flags }) { | ||
if (!state.connecting[token]) { | ||
Vue.set(state.connecting, token, {}) | ||
} | ||
Vue.set(state.connecting[token], sessionId, flags) | ||
}, | ||
|
||
finishedConnecting(state, { token, sessionId }) { | ||
if (state.connecting[token] && state.connecting[token][sessionId]) { | ||
Vue.delete(state.connecting[token], sessionId) | ||
|
@@ -777,6 +779,8 @@ const actions = { | |
}, | ||
|
||
async joinCall({ commit, getters }, { token, participantIdentifier, flags, silent, recordingConsent }) { | ||
commit('connecting', { token, sessionId: participantIdentifier.sessionId, flags }) | ||
|
||
if (!participantIdentifier?.sessionId) { | ||
console.error('Trying to join call without sessionId') | ||
return | ||
|
@@ -788,28 +792,31 @@ const actions = { | |
return | ||
} | ||
|
||
commit('setInCall', { | ||
token, | ||
sessionId: participantIdentifier.sessionId, | ||
flags, | ||
// Preparing the event listener for the signaling-join-call event | ||
EventBus.once('signaling-join-call', () => { | ||
commit('setInCall', { | ||
token, | ||
sessionId: participantIdentifier.sessionId, | ||
flags, | ||
}) | ||
commit('finishedConnecting', { token, sessionId: participantIdentifier.sessionId }) | ||
}) | ||
|
||
const actualFlags = await joinCall(token, flags, silent, recordingConsent) | ||
|
||
const updatedData = { | ||
inCall: actualFlags, | ||
} | ||
commit('updateParticipant', { token, attendeeId: attendee.attendeeId, updatedData }) | ||
|
||
EventBus.once('signaling-users-in-room', () => { | ||
// Preparing the event listener for the signaling-join-call-failed event | ||
EventBus.once('signaling-join-call-failed', () => { | ||
commit('finishedConnecting', { token, sessionId: participantIdentifier.sessionId }) | ||
}) | ||
|
||
setTimeout(() => { | ||
// If by accident we never receive a users list, just switch to | ||
// "Waiting for others to join the call โฆ" after some seconds. | ||
commit('finishedConnecting', { token, sessionId: participantIdentifier.sessionId }) | ||
}, 10000) | ||
Comment on lines
-808
to
-812
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's guaranteed to receive one of the above signaling events as we are the base server |
||
try { | ||
const actualFlags = await joinCall(token, flags, silent, recordingConsent) | ||
const updatedData = { | ||
inCall: actualFlags, | ||
} | ||
commit('updateParticipant', { token, attendeeId: attendee.attendeeId, updatedData }) | ||
} catch (e) { | ||
console.error(e) | ||
|
||
} | ||
}, | ||
|
||
async leaveCall({ commit, getters }, { token, participantIdentifier, all = false }) { | ||
|
@@ -1128,6 +1135,10 @@ const actions = { | |
setPhoneMute(context, { callid, value }) { | ||
context.commit('setPhoneMute', { callid, value }) | ||
}, | ||
|
||
clearConnectionFailed(context, token) { | ||
context.commit('clearConnectionFailed', token) | ||
} | ||
} | ||
|
||
export default { state, mutations, getters, actions } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have useStore composable, it should be better to use it here