KI-AGENT: Kamera und Bildschirmfreigabe getrennt anzeigen

This commit is contained in:
2026-05-18 19:28:53 +02:00
parent 77eabe7e18
commit 24c09d7891

View File

@@ -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(() => {
<video
v-if="tile.videoTrack"
:ref="(element) => setMatrixCallVideoElement(tile.id, element)"
class="h-full w-full object-cover"
class="h-full w-full"
:class="tile.screenSharing ? 'object-contain bg-black' : 'object-cover'"
autoplay
playsinline
:muted="tile.local"
@@ -1380,11 +1403,18 @@ onBeforeUnmount(() => {
</span>
<div class="flex items-center gap-2">
<UIcon
v-if="tile.screenSharing"
name="i-heroicons-computer-desktop"
class="size-4"
/>
<UIcon
v-if="!tile.screenSharing"
:name="tile.microphoneEnabled ? 'i-heroicons-microphone' : 'i-heroicons-microphone'"
class="size-4"
:class="tile.microphoneEnabled ? 'opacity-100' : 'opacity-35'"
/>
<UIcon
v-if="!tile.screenSharing"
:name="tile.cameraEnabled ? 'i-heroicons-video-camera' : 'i-heroicons-video-camera-slash'"
class="size-4"
/>