Skip to content
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

[vue3] fix: fix unmount issues and call reactivity #12461

Draft
wants to merge 5 commits into
base: vue3
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions src/components/CallView/CallView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export default {
},

callParticipantModels() {
return callParticipantCollection.callParticipantModels.value.filter(callParticipantModel => !callParticipantModel.attributes.internal)
return callParticipantCollection.callParticipantModels.filter(callParticipantModel => !callParticipantModel.attributes.internal)
},

callParticipantModelsWithScreen() {
Expand Down Expand Up @@ -362,9 +362,12 @@ export default {
this.adjustSimulcastQuality()
},

speakers(value) {
if (value) {
this._setPromotedParticipant()
speakers: {
deep: true,
handler(value) {
if (value) {
this._setPromotedParticipant()
}
}
},

Expand All @@ -375,9 +378,16 @@ export default {
},

screens() {
console.log('screens watcher')
this._setScreenVisible()

},
// screens: {
// deep: true,
// handler() {
// this._setScreenVisible()
// }
// },

callParticipantModelsWithScreen(newValue, previousValue) {
// Everytime a new screen is shared, switch to promoted view
Expand Down Expand Up @@ -455,6 +465,7 @@ export default {
* @param {Array} models the array of CallParticipantModels
*/
updateDataFromCallParticipantModels(models) {
console.log('updateDataFromCallParticipantModels', models)
const addedModels = models.filter(model => !this.sharedDatas[model.attributes.peerId])
const removedModelIds = Object.keys(this.sharedDatas).filter(sharedDataId => models.find(model => model.attributes.peerId === sharedDataId) === undefined)

Expand All @@ -464,15 +475,15 @@ export default {
delete this.sharedDatas[removedModelId]

this.speakingUnwatchers[removedModelId]()
// Not reactive, but not a problem
// FIXME Not reactive, but not a problem?
delete this.speakingUnwatchers[removedModelId]

this.screenUnwatchers[removedModelId]()
// Not reactive, but not a problem
// FIXME Not reactive, but not a problem?
delete this.screenUnwatchers[removedModelId]

this.raisedHandUnwatchers[removedModelId]()
// Not reactive, but not a problem
// FIXME Not reactive, but not a problem?
delete this.raisedHandUnwatchers[removedModelId]

const index = this.speakers.findIndex(speaker => speaker.id === removedModelId)
Expand All @@ -490,7 +501,7 @@ export default {

this.sharedDatas[addedModel.attributes.peerId] = sharedData

// Not reactive, but not a problem
// FIXME Not reactive, but not a problem?
this.speakingUnwatchers[addedModel.attributes.peerId] = this.$watch(function() {
return addedModel.attributes.speaking
}, function(speaking) {
Expand All @@ -502,14 +513,14 @@ export default {
active: false,
})

// Not reactive, but not a problem
// FIXME Not reactive, but not a problem?
this.screenUnwatchers[addedModel.attributes.peerId] = this.$watch(function() {
return addedModel.attributes.screen
}, function(screen) {
this._setScreenAvailable(addedModel.attributes.peerId, screen)
})

// Not reactive, but not a problem
// FIXME Not reactive, but not a problem? - at least works
this.raisedHandUnwatchers[addedModel.attributes.peerId] = this.$watch(function() {
return addedModel.attributes.raisedHand
}, function(raisedHand) {
Expand Down Expand Up @@ -578,6 +589,7 @@ export default {
},

_setScreenAvailable(id, screen) {
console.log('_setScreenAvailable', id, screen)
if (screen) {
this.screens.unshift(id)

Expand Down Expand Up @@ -625,6 +637,7 @@ export default {
},

_setScreenVisible() {
console.log('_setScreenVisible', this.sharedDatas)
this.localSharedData.screenVisible = false

Object.values(this.sharedDatas).forEach(sharedData => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/CallView/shared/VideoVue.vue
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ export default {
},

updateVideoAspectRatio() {
if (!this.isBig) {
if (!this.isBig || !this.model.attributes.stream) {
return
}

Expand Down
6 changes: 5 additions & 1 deletion src/components/MessagesList/MessagesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,10 @@ export default {
},

checkSticky() {
if (!this.$refs.scroller) {
return
}

const ulElements = this.$refs['dateGroup-' + this.token]
if (!ulElements) {
return
Expand All @@ -807,7 +811,7 @@ export default {
this.isScrolling = true
this.endScrollTimeout = setTimeout(this.endScroll, 3000)
// handle sticky date
if (this.$refs.scroller.scrollTop === 0) {
if (this.$refs.scroller?.scrollTop === 0) {
this.stickyDate = null
} else {
this.checkSticky()
Expand Down
2 changes: 1 addition & 1 deletion src/components/TopBar/TopBarMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ export default {
methods: {
t,
forceMuteOthers() {
callParticipantCollection.callParticipantModels.value.forEach(callParticipantModel => {
callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
callParticipantModel.forceMute()
})
},
Expand Down
4 changes: 2 additions & 2 deletions src/utils/webrtc/CallParticipantsAudioPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function CallParticipantsAudioPlayer(callParticipantCollection, m
this._callParticipantCollection.on('add', this._handleCallParticipantAddedBound)
this._callParticipantCollection.on('remove', this._handleCallParticipantRemovedBound)

this._callParticipantCollection.callParticipantModels.value.forEach(callParticipantModel => {
this._callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
this._handleCallParticipantAddedBound(this._callParticipantCollection, callParticipantModel)
})
}
Expand All @@ -60,7 +60,7 @@ CallParticipantsAudioPlayer.prototype = {
this._callParticipantCollection.off('add', this._handleCallParticipantAddedBound)
this._callParticipantCollection.off('remove', this._handleCallParticipantRemovedBound)

this._callParticipantCollection.callParticipantModels.value.forEach(callParticipantModel => {
this._callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
this._handleCallParticipantRemovedBound(this._callParticipantCollection, callParticipantModel)
})

Expand Down
6 changes: 3 additions & 3 deletions src/utils/webrtc/CallParticipantsAudioPlayer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe('CallParticipantsAudioPlayer', () => {
* @param {object} callParticipantModel the CallParticipantModel to add.
*/
function addCallParticipantModel(callParticipantModel) {
callParticipantCollection.callParticipantModels.value.push(callParticipantModel)
callParticipantCollection.callParticipantModels.push(callParticipantModel)

callParticipantCollection._trigger('add', [callParticipantModel])
}
Expand All @@ -82,8 +82,8 @@ describe('CallParticipantsAudioPlayer', () => {
* @param {object} callParticipantModel the CallParticipantModel to remove.
*/
function removeCallParticipantModel(callParticipantModel) {
const index = callParticipantCollection.callParticipantModels.value.indexOf(callParticipantModel)
callParticipantCollection.callParticipantModels.value.splice(index, 1)
const index = callParticipantCollection.callParticipantModels.indexOf(callParticipantModel)
callParticipantCollection.callParticipantModels.splice(index, 1)

callParticipantCollection._trigger('remove', [callParticipantModel])
}
Expand Down
6 changes: 3 additions & 3 deletions src/utils/webrtc/SentVideoQualityThrottler.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ SentVideoQualityThrottler.prototype = {
this._callParticipantCollection.on('add', this._handleAddParticipantBound)
this._callParticipantCollection.on('remove', this._handleRemoveParticipantBound)

this._callParticipantCollection.callParticipantModels.value.forEach(callParticipantModel => {
this._callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
callParticipantModel.on('change:videoAvailable', this._adjustVideoQualityIfNeededBound)
callParticipantModel.on('change:audioAvailable', this._adjustVideoQualityIfNeededBound)
})
Expand All @@ -103,7 +103,7 @@ SentVideoQualityThrottler.prototype = {
this._callParticipantCollection.off('add', this._handleAddParticipantBound)
this._callParticipantCollection.off('remove', this._handleRemoveParticipantBound)

this._callParticipantCollection.callParticipantModels.value.forEach(callParticipantModel => {
this._callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
callParticipantModel.off('change:videoAvailable', this._adjustVideoQualityIfNeededBound)
callParticipantModel.off('change:audioAvailable', this._adjustVideoQualityIfNeededBound)
})
Expand Down Expand Up @@ -171,7 +171,7 @@ SentVideoQualityThrottler.prototype = {

let availableVideosCount = 0
let availableAudiosCount = 0
this._callParticipantCollection.callParticipantModels.value.forEach(callParticipantModel => {
this._callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
if (callParticipantModel.get('videoAvailable')) {
availableVideosCount++
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/webrtc/SpeakingStatusHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default class SpeakingStatusHandler {
this.#callParticipantCollection.off('add', this.#handleAddParticipantBound)
this.#callParticipantCollection.off('remove', this.#handleRemoveParticipantBound)

this.#callParticipantCollection.callParticipantModels.value.forEach(callParticipantModel => {
this.#callParticipantCollection.callParticipantModels.forEach(callParticipantModel => {
callParticipantModel.off('change:speaking', this.#handleSpeakingBound)
callParticipantModel.off('change:stoppedSpeaking', this.#handleSpeakingBound)
})
Expand Down
15 changes: 7 additions & 8 deletions src/utils/webrtc/models/CallParticipantCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { ref } from 'vue'
import { reactive } from 'vue'

import CallParticipantModel from './CallParticipantModel.js'
import EmitterMixin from '../../EmitterMixin.js'
Expand All @@ -15,36 +15,35 @@ export default function CallParticipantCollection() {

this._superEmitterMixin()

// FIXME: use reactive instead of ref after migration to vue 3
this.callParticipantModels = ref([])
this.callParticipantModels = reactive([])

}

CallParticipantCollection.prototype = {

add(options) {
const callParticipantModel = new CallParticipantModel(options)
this.callParticipantModels.value.push(callParticipantModel)
this.callParticipantModels.push(callParticipantModel)

this._trigger('add', [callParticipantModel])

return callParticipantModel
},

get(peerId) {
return this.callParticipantModels.value.find(function(callParticipantModel) {
return this.callParticipantModels.find(function(callParticipantModel) {
return callParticipantModel.attributes.peerId === peerId
})
},

remove(peerId) {
const index = this.callParticipantModels.value.findIndex(function(callParticipantModel) {
const index = this.callParticipantModels.findIndex(function(callParticipantModel) {
return callParticipantModel.attributes.peerId === peerId
})
if (index !== -1) {
const callParticipantModel = this.callParticipantModels.value[index]
const callParticipantModel = this.callParticipantModels[index]

this.callParticipantModels.value.splice(index, 1)
this.callParticipantModels.splice(index, 1)

this._trigger('remove', [callParticipantModel])

Expand Down
14 changes: 8 additions & 6 deletions src/utils/webrtc/models/CallParticipantModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { reactive, toRaw } from 'vue'

import EmitterMixin from '../../EmitterMixin.js'

Expand All @@ -26,7 +27,7 @@ export default function CallParticipantModel(options) {

this._superEmitterMixin()

this.attributes = {
this.attributes = reactive({
peerId: null,
nextcloudSessionId: null,
peer: null,
Expand All @@ -53,7 +54,7 @@ export default function CallParticipantModel(options) {
state: false,
timestamp: null,
},
}
})

this.set('peerId', options.peerId)

Expand Down Expand Up @@ -115,25 +116,26 @@ CallParticipantModel.prototype = {
},

_handlePeerStreamAdded(peer) {
if (this.get('peer') === peer) {
// FIXME store as a non-reactive, raw value using toRaw to not have proxy created for Peer at all.
if (toRaw(this.get('peer')) === toRaw(peer)) {
this.set('stream', this.get('peer').stream || null)

// "peer.nick" is set only for users and when the MCU is not used.
if (this.get('peer').nick !== undefined) {
this.set('name', this.get('peer').nick)
}
} else if (this.get('screenPeer') === peer) {
} else if (toRaw(this.get('screenPeer')) === toRaw(peer)) {
this.set('screen', this.get('screenPeer').stream || null)
}
},

_handlePeerStreamRemoved(peer) {
if (this.get('peer') === peer) {
if (toRaw(this.get('peer')) === toRaw(peer)) {
this.set('stream', null)
this.set('audioAvailable', undefined)
this.set('speaking', undefined)
this.set('videoAvailable', undefined)
} else if (this.get('screenPeer') === peer) {
} else if (toRaw(this.get('screenPeer')) === toRaw(peer)) {
this.set('screen', null)
}
},
Expand Down