From 5ee5308311a9b6f204ba6c4b5c162331814937fc Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Fri, 20 Jun 2025 14:18:14 +0200 Subject: [PATCH 1/5] fix(call): do not hide participants videos if not initialised yet Signed-off-by: Maksim Sukharev --- src/components/CallView/Grid/Grid.vue | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/CallView/Grid/Grid.vue b/src/components/CallView/Grid/Grid.vue index 703cb4ce97c..feb2525b63f 100644 --- a/src/components/CallView/Grid/Grid.vue +++ b/src/components/CallView/Grid/Grid.vue @@ -515,10 +515,6 @@ export default { return this.videos } - if (!this.participantsInitialised) { - return [] - } - const objectMap = { modelsWithScreenshare: [], modelsTempPromoted: [], @@ -538,7 +534,7 @@ export default { objectMap.modelsTempPromoted.push(model) } else if (this.isModelWithVideo(model)) { videoTilesMap.set(model.attributes.nextcloudSessionId, model) - } else if (this.isModelWithAudio(model)) { + } else if (this.participantsInitialised && this.isModelWithAudio(model)) { audioTilesMap.set(model.attributes.nextcloudSessionId, model) } else { objectMap.modelsWithNoPermissions.push(model) From 2a6cea164f631b212f7250c182c34044c048a631 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Fri, 20 Jun 2025 14:19:27 +0200 Subject: [PATCH 2/5] fix(conversationStore): pass permissions to dummy participant - when joining the call, it will not trigger the request Signed-off-by: Maksim Sukharev --- src/store/conversationsStore.js | 1 + src/store/conversationsStore.spec.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/store/conversationsStore.js b/src/store/conversationsStore.js index f62cdc3208d..f19089ed0ba 100644 --- a/src/store/conversationsStore.js +++ b/src/store/conversationsStore.js @@ -324,6 +324,7 @@ const actions = { lastPing: conversation.lastPing, sessionIds: [conversation.sessionId], participantType: conversation.participantType, + permissions: conversation.permissions, attendeeId: conversation.attendeeId, actorType: conversation.actorType, actorId: conversation.actorId, // FIXME check public share page handling diff --git a/src/store/conversationsStore.spec.js b/src/store/conversationsStore.spec.js index 14bc7213e5a..34f99cc14fd 100644 --- a/src/store/conversationsStore.spec.js +++ b/src/store/conversationsStore.spec.js @@ -107,6 +107,7 @@ describe('conversationsStore', () => { attendeeId: 'attendee-id-1', actorType: ATTENDEE.ACTOR_TYPE.USERS, actorId: 'actor-id', + permissions: PARTICIPANT.PERMISSIONS.CUSTOM, defaultPermissions: PARTICIPANT.PERMISSIONS.CUSTOM, callPermissions: PARTICIPANT.PERMISSIONS.CUSTOM, lastMessage: { ...previousLastMessage }, @@ -162,6 +163,7 @@ describe('conversationsStore', () => { inCall: PARTICIPANT.CALL_FLAG.DISCONNECTED, lastPing: 600, participantType: PARTICIPANT.TYPE.USER, + permissions: PARTICIPANT.PERMISSIONS.CUSTOM, sessionIds: [ 'session-id-1', ], @@ -194,6 +196,7 @@ describe('conversationsStore', () => { inCall: PARTICIPANT.CALL_FLAG.DISCONNECTED, lastPing: 600, participantType: PARTICIPANT.TYPE.USER, + permissions: PARTICIPANT.PERMISSIONS.CUSTOM, sessionIds: [ 'session-id-1', ], From 8de68ecd67a2bb6fce274686203d6a61f8b9ddef Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Fri, 20 Jun 2025 14:34:51 +0200 Subject: [PATCH 3/5] fix(ParticipantsTab): adjust signaling update logic to work for guests Signed-off-by: Maksim Sukharev --- .../Participants/ParticipantsTab.vue | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/RightSidebar/Participants/ParticipantsTab.vue b/src/components/RightSidebar/Participants/ParticipantsTab.vue index 04327a8d231..da13b52bdfb 100644 --- a/src/components/RightSidebar/Participants/ParticipantsTab.vue +++ b/src/components/RightSidebar/Participants/ParticipantsTab.vue @@ -219,10 +219,6 @@ export default { return [CONVERSATION.TYPE.ONE_TO_ONE, CONVERSATION.TYPE.ONE_TO_ONE_FORMER].includes(this.conversation.type) }, - userId() { - return this.actorStore.userId - }, - canAddPhones() { const canModerateSipDialOut = hasTalkFeature(this.token, 'sip-support-dialout') && getTalkConfig(this.token, 'call', 'sip-enabled') @@ -267,9 +263,10 @@ export default { methods: { t, - async updateUsers(usersList) { - const currentUser = usersList.flat().find((user) => user.userId === this.userId) - const currentParticipant = this.participants.find((user) => user.userId === this.userId) + async updateUsers([users]) { + const currentUser = users.find((user) => { + return user.userId ? user.userId === this.actorStore.userId : user.actorId === this.actorStore.actorId + }) if (!currentUser) { return } @@ -277,7 +274,10 @@ export default { if (currentUser.participantPermissions !== this.conversation.permissions) { await this.$store.dispatch('fetchConversation', { token: this.token }) } - if (currentUser.participantPermissions !== currentParticipant?.permissions) { + + const currentParticipant = this.$store.getters.getParticipant(this.token, this.actorStore.attendeeId) + if (currentParticipant && this.$store.getters.isModeratorOrUser + && currentUser.participantPermissions !== currentParticipant?.permissions) { await this.cancelableGetParticipants() } }, From 6af2b3af0918a0f5578488a2280fcd48e981c703 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Fri, 20 Jun 2025 14:43:26 +0200 Subject: [PATCH 4/5] fix(useGetParticipants): instantly get participants list (with experimental flag) Signed-off-by: Maksim Sukharev --- src/composables/useGetParticipants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/composables/useGetParticipants.js b/src/composables/useGetParticipants.js index 268e19c1e32..60605a7f909 100644 --- a/src/composables/useGetParticipants.js +++ b/src/composables/useGetParticipants.js @@ -90,7 +90,7 @@ export function useGetParticipants(isActive = ref(true), isTopBar = true) { } const onJoinedConversation = () => { - if (isOneToOneConversation.value) { + if (isOneToOneConversation.value || experimentalUpdateParticipants) { cancelableGetParticipants() } else { nextTick(() => throttleUpdateParticipants()) From 37216e0dc192d7f676001795aa2e95dd8dcff291 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Fri, 20 Jun 2025 14:44:17 +0200 Subject: [PATCH 5/5] fix(useGetParticipants): better handle canceling requests Signed-off-by: Maksim Sukharev --- src/composables/useGetParticipants.js | 42 ++++++++++++++++----------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/composables/useGetParticipants.js b/src/composables/useGetParticipants.js index 60605a7f909..0233cd5d83d 100644 --- a/src/composables/useGetParticipants.js +++ b/src/composables/useGetParticipants.js @@ -120,36 +120,26 @@ export function useGetParticipants(isActive = ref(true), isTopBar = true) { } fetchingParticipants = true - - // Cancel the parallel request queue to not fetch twice - clearTimeout(throttleFastUpdateTimeout) - throttleFastUpdateTimeout = null - clearTimeout(throttleSlowUpdateTimeout) - throttleSlowUpdateTimeout = null - clearTimeout(throttleLongUpdateTimeout) - throttleLongUpdateTimeout = null + cancelPendingUpdates() await store.dispatch('fetchParticipants', { token: token.value }) fetchingParticipants = false } const throttleFastUpdate = () => { - if (throttleFastUpdateTimeout) { - return + if (!fetchingParticipants && !throttleFastUpdateTimeout) { + throttleFastUpdateTimeout = setTimeout(cancelableGetParticipants, 3_000) } - throttleFastUpdateTimeout = setTimeout(cancelableGetParticipants, 3_000) } const throttleSlowUpdate = () => { - if (throttleSlowUpdateTimeout) { - return + if (!fetchingParticipants && !throttleSlowUpdateTimeout) { + throttleSlowUpdateTimeout = setTimeout(cancelableGetParticipants, 15_000) } - throttleSlowUpdateTimeout = setTimeout(cancelableGetParticipants, 15_000) } const throttleLongUpdate = () => { - if (throttleLongUpdateTimeout) { - return + if (!fetchingParticipants && !throttleLongUpdateTimeout) { + throttleLongUpdateTimeout = setTimeout(cancelableGetParticipants, 60_000) } - throttleLongUpdateTimeout = setTimeout(cancelableGetParticipants, 60_000) } onMounted(() => { @@ -158,6 +148,10 @@ export function useGetParticipants(isActive = ref(true), isTopBar = true) { } }) + watch(token, () => { + cancelPendingUpdates() + }) + watch(isActive, (newValue) => { if (newValue && pendingChanges) { throttleUpdateParticipants() @@ -165,11 +159,25 @@ export function useGetParticipants(isActive = ref(true), isTopBar = true) { }) onBeforeUnmount(() => { + cancelPendingUpdates() if (isTopBar) { stopGetParticipants() } }) + /** + * Cancel scheduled participant list updates + * Applies to all parallel queues to not fetch twice + */ + function cancelPendingUpdates() { + clearTimeout(throttleFastUpdateTimeout) + throttleFastUpdateTimeout = null + clearTimeout(throttleSlowUpdateTimeout) + throttleSlowUpdateTimeout = null + clearTimeout(throttleLongUpdateTimeout) + throttleLongUpdateTimeout = null + } + return { cancelableGetParticipants, }