65 lines
1.4 KiB
Vue
65 lines
1.4 KiB
Vue
<template>
|
|
<div class="grid grid-cols-[1fr_1fr] gap-2">
|
|
<GalleryCard
|
|
v-for="item in gallery"
|
|
:key="item.client.socketId"
|
|
:client="item.client"
|
|
:stream="item.stream"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { ChadClient } from '#shared/types'
|
|
|
|
interface GalleryItem {
|
|
client: ChadClient
|
|
stream: MediaStream
|
|
}
|
|
|
|
definePageMeta({
|
|
name: 'Gallery',
|
|
})
|
|
|
|
const { videoProducer, shareProducer } = useMediasoup()
|
|
const { clients, me } = useClients()
|
|
|
|
const gallery = computed(() => {
|
|
return clients.value.reduce<GalleryItem[]>(
|
|
(acc, client) => {
|
|
const { streaming, videoConsumers, shareConsumers } = useClient(client.socketId)
|
|
|
|
if (!streaming.value)
|
|
return acc
|
|
|
|
for (const consumer of [...videoConsumers.value, ...shareConsumers.value]) {
|
|
acc.push({
|
|
client,
|
|
stream: new MediaStream([consumer.raw.track]),
|
|
})
|
|
}
|
|
|
|
return acc
|
|
},
|
|
[videoProducer.value, shareProducer.value].reduce<GalleryItem[]>((acc, producer) => {
|
|
if (!me.value || !producer || !producer.raw.track)
|
|
return acc
|
|
|
|
acc.push({
|
|
client: me.value,
|
|
stream: new MediaStream([producer.raw.track]),
|
|
})
|
|
|
|
return acc
|
|
}, []),
|
|
)
|
|
})
|
|
|
|
watch(gallery, (gallery) => {
|
|
if (gallery.length > 0)
|
|
return
|
|
|
|
navigateTo({ name: 'Index' })
|
|
})
|
|
</script>
|