diff --git a/frontend/pages/communication/chat.vue b/frontend/pages/communication/chat.vue index 8c23b01..72af02b 100644 --- a/frontend/pages/communication/chat.vue +++ b/frontend/pages/communication/chat.vue @@ -91,7 +91,9 @@ const matrixCallStateLabel = computed(() => { return labels[String(matrixCallState.value).toLowerCase()] || matrixCallState.value }) -const matrixCallParticipantCount = computed(() => matrixCallTiles.value.length) +const matrixCallParticipantCount = computed(() => + new Set(matrixCallTiles.value.map((tile) => tile.identity)).size +) const matrixCallDurationLabel = computed(() => { if (!matrixCallStartedAt.value) return "00:00" @@ -410,7 +412,7 @@ const openMatrixCall = async (mode = "video") => { } } -const getParticipantTile = (participant, local = false) => { +const getParticipantTiles = (participant, local = false) => { const publications = participant.getTrackPublications?.() || [] const screenSharePublication = publications.find((publication) => publication.kind === Track.Kind.Video && @@ -425,20 +427,40 @@ const getParticipantTile = (participant, local = false) => { const audioPublication = publications.find((publication) => publication.kind === Track.Kind.Audio && publication.track ) - const videoPublication = screenSharePublication || cameraPublication - - return { - id: local ? "local" : participant.sid || participant.identity, + const participantId = local ? "local" : participant.sid || participant.identity + const name = local ? "Du" : participant.name || participant.identity + const participantTile = { + id: `${participantId}-camera`, identity: participant.identity, - name: local ? "Du" : participant.name || participant.identity, + name, local, speaking: participant.isSpeaking, - screenSharing: Boolean(screenSharePublication?.track), - videoTrack: videoPublication?.track || null, + screenSharing: false, + videoTrack: cameraPublication?.track || null, audioTrack: audioPublication?.track || null, cameraEnabled: participant.isCameraEnabled, microphoneEnabled: participant.isMicrophoneEnabled, } + + if (!screenSharePublication?.track) { + return [participantTile] + } + + return [ + { + id: `${participantId}-screen`, + identity: participant.identity, + name, + local, + speaking: false, + screenSharing: true, + videoTrack: screenSharePublication.track, + audioTrack: null, + cameraEnabled: participant.isCameraEnabled, + microphoneEnabled: participant.isMicrophoneEnabled, + }, + participantTile + ] } const attachMatrixCallMedia = async () => { @@ -468,9 +490,9 @@ const refreshMatrixCallTiles = async () => { matrixCallAudioContainer.value?.replaceChildren() matrixCallTiles.value = [ - getParticipantTile(matrixLiveKitRoom.localParticipant, true), - ...Array.from(matrixLiveKitRoom.remoteParticipants.values()).map((participant) => - getParticipantTile(participant) + ...getParticipantTiles(matrixLiveKitRoom.localParticipant, true), + ...Array.from(matrixLiveKitRoom.remoteParticipants.values()).flatMap((participant) => + getParticipantTiles(participant) ) ].sort((a, b) => Number(b.screenSharing) - Number(a.screenSharing)) @@ -1360,7 +1382,8 @@ onBeforeUnmount(() => {