Skip to content

Commit

Permalink
fix(Grid): refactor methods for dynamic ordering. Update the array it…
Browse files Browse the repository at this point in the history
…ems with patching instead of overwriting it.

Signed-off-by: DorraJaouad <dorra.jaoued7@gmail.com>
  • Loading branch information
DorraJaouad committed May 24, 2024
1 parent bd34996 commit fa6279f
Showing 1 changed file with 74 additions and 30 deletions.
104 changes: 74 additions & 30 deletions src/components/CallView/Grid/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ import LocalVideo from '../shared/LocalVideo.vue'
import VideoBottomBar from '../shared/VideoBottomBar.vue'
import VideoVue from '../shared/VideoVue.vue'

import { PARTICIPANT } from '../../../constants.js'
import { PARTICIPANT, ATTENDEE } from '../../../constants.js'

// Max number of videos per page. `0`, the default value, means no cap
const videosCap = parseInt(loadState('spreed', 'grid_videos_limit'), 10) || 0
Expand Down Expand Up @@ -270,8 +270,9 @@ export default {
// Timer for the videos bottom bar
showVideoOverlayTimer: null,
debounceMakeGrid: () => {},
orderedVideos: [],
videosOfModerators: [],
videosOfSpeakersNonModerators: [],
videosWithoutPermissions: [],
}
},

Expand Down Expand Up @@ -490,6 +491,17 @@ export default {
participantsInitialised() {
return this.$store.getters.participantsInitialised(this.token)
},

actorType() {
return this.$store.getters.getActorType()
},

orderedVideos() {
if (this.actorType === ATTENDEE.ACTOR_TYPE.GUESTS) {
return this.videos
}
return [...this.videosOfModerators, ...this.videosOfSpeakersNonModerators, ...this.videosWithoutPermissions]
},
},

watch: {
Expand Down Expand Up @@ -538,17 +550,18 @@ export default {

callParticipantModels: {
immediate: true,
handler() {
handler(newModels, oldModels) {
if (!this.participantsInitialised) {
return
}
this.orderedVideos = this.orderVideos(this.videos)
// TODO: patch the array with the new models
this.patchOrderedVideos(newModels)
},
},

participantsInitialised(value) {
if (value) {
this.orderedVideos = this.orderVideos(this.videos)
this.orderVideos(this.videos)
}
},

Expand All @@ -557,9 +570,8 @@ export default {
return
}
speakers.forEach(speaker => {
this.orderedVideos = this.orderVideos(this.orderedVideos, speaker)
this.promoteSpeaker(speaker)
})

}
},

Expand Down Expand Up @@ -865,35 +877,42 @@ export default {
return callParticipantModel.attributes.peerId === this.$store.getters.selectedVideoPeerId
},

orderVideos(initialVideos, model = null) {
// If model is passed, that model is moved to the front of the array
if (model) {
// if model is already in the first page, do nothing
if (initialVideos.slice(0, this.slots).find(video => video.attributes.peerId === model.attributes.peerId)) {
return initialVideos
}
const videosOfSpeakers = initialVideos.filter((video) => {
promoteSpeaker(model) {
// if model is already in the first page, do nothing
if (this.orderedVideos.slice(0, this.slots).find(video => video.attributes.peerId === model.attributes.peerId)) {
return
}
const participant = this.$store.getters.getParticipantByPeerId(this.token, model.attributes.peerId)
// check if it is a moderator
if (MODERATOR_TYPES.includes(participant.participantType)) {
// remove the model from its current position
this.videosOfModerators = this.videosOfModerators.filter((video) => {
return video.attributes.peerId !== model.attributes.peerId
})
const participant = this.$store.getters.getParticipantByPeerId(this.token, model.attributes.peerId)
// check if it is a moderator
if (MODERATOR_TYPES.includes(participant.participantType)) {
// add the model
videosOfSpeakers.unshift(model)
} else {
videosOfSpeakers.splice(this.videosOfModerators.length, 0, model)
}

return videosOfSpeakers
// add the model
this.videosOfModerators.unshift(model)
} else {
// remove the model from its current position
this.videosOfSpeakersNonModerators = this.videosOfSpeakersNonModerators.filter((video) => {
return video.attributes.peerId !== model.attributes.peerId
})
// add the model
this.videosOfSpeakersNonModerators.unshift(model)
}
},

orderVideos(initialVideos) {
// Guests don't have participants data, so we can't order them
if (this.actorType === ATTENDEE.ACTOR_TYPE.GUESTS) {
return
}
// videos are ordered as follows:
// 1. videos of users who has speaker per
// 2. videos of users who don't have permissions
// If the user has the permission to speak, the video is shown first
this.videosOfModerators = []
const videosOfSpeakers = []
const videosWithoutPermissions = []
this.videosOfSpeakersNonModerators = []
this.videosWithoutPermissions = []
initialVideos.forEach((video) => {
// FIX !!!!: the store is not loaded when joining the call for the first time
const participant = this.$store.getters.getParticipantByPeerId(this.token, video.attributes.peerId)
Expand All @@ -904,14 +923,39 @@ export default {
if (MODERATOR_TYPES.includes(participant.participantType)) {
this.videosOfModerators.push(video)
} else {
videosOfSpeakers.push(video)
this.videosOfSpeakersNonModerators.push(video)
}
} else {
this.videosWithoutPermissions.push(video)
}
})
},

patchOrderedVideos(newVideos) {
const addedVideos = newVideos.filter(model => !this.orderedVideos.includes(model))
const removedVideos = this.orderedVideos.filter(model => !newVideos.includes(model))

// Place the added videos in the correct position
addedVideos.forEach(model => {
const participant = this.$store.getters.getParticipantByPeerId(this.token, model.attributes.peerId)

if (participant?.permissions & PARTICIPANT.PERMISSIONS.PUBLISH_AUDIO) {
if (MODERATOR_TYPES.includes(participant.participantType)) {
this.videosOfModerators.push(model)
} else {
this.videosOfSpeakersNonModerators.push(model)
}
} else {
videosWithoutPermissions.push(video)
this.videosWithoutPermissions.push(model)
}
})

return this.videosOfModerators.concat(videosOfSpeakers, videosWithoutPermissions)
// Remove the removed videos
removedVideos.forEach(model => {
this.videosOfModerators = this.videosOfModerators.filter(video => video.attributes.peerId !== model.attributes.peerId)
this.videosOfSpeakersNonModerators = this.videosOfSpeakersNonModerators.filter(video => video.attributes.peerId !== model.attributes.peerId)
this.videosWithoutPermissions = this.videosWithoutPermissions.filter(video => video.attributes.peerId !== model.attributes.peerId)
})

},

Expand Down

0 comments on commit fa6279f

Please sign in to comment.