forked from Shiloh/remnantchat
refactor: decouple peer room hooks and clean up audio
This commit is contained in:
parent
0a05d197cb
commit
49c513b8e1
@ -39,6 +39,9 @@ export function useRoom(
|
|||||||
const [peerRoom] = useState(
|
const [peerRoom] = useState(
|
||||||
() => new PeerRoom({ password: password ?? roomId, ...roomConfig }, roomId)
|
() => new PeerRoom({ password: password ?? roomId, ...roomConfig }, roomId)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
peerRoom.flush()
|
||||||
|
|
||||||
const [numberOfPeers, setNumberOfPeers] = useState(1) // Includes this peer
|
const [numberOfPeers, setNumberOfPeers] = useState(1) // Includes this peer
|
||||||
const shellContext = useContext(ShellContext)
|
const shellContext = useContext(ShellContext)
|
||||||
const settingsContext = useContext(SettingsContext)
|
const settingsContext = useContext(SettingsContext)
|
||||||
@ -158,8 +161,6 @@ export function useRoom(
|
|||||||
const newNumberOfPeers = numberOfPeers + 1
|
const newNumberOfPeers = numberOfPeers + 1
|
||||||
setNumberOfPeers(newNumberOfPeers)
|
setNumberOfPeers(newNumberOfPeers)
|
||||||
shellContext.setNumberOfPeers(newNumberOfPeers)
|
shellContext.setNumberOfPeers(newNumberOfPeers)
|
||||||
|
|
||||||
handleAudioForNewPeer(peerId)
|
|
||||||
;(async () => {
|
;(async () => {
|
||||||
try {
|
try {
|
||||||
const promises: Promise<any>[] = [sendPeerId(userId, peerId)]
|
const promises: Promise<any>[] = [sendPeerId(userId, peerId)]
|
||||||
@ -177,6 +178,10 @@ export function useRoom(
|
|||||||
})()
|
})()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
peerRoom.onPeerJoin((peerId: string) => {
|
||||||
|
handleAudioForNewPeer(peerId)
|
||||||
|
})
|
||||||
|
|
||||||
peerRoom.onPeerLeave((peerId: string) => {
|
peerRoom.onPeerLeave((peerId: string) => {
|
||||||
const peerIndex = shellContext.peerList.findIndex(
|
const peerIndex = shellContext.peerList.findIndex(
|
||||||
peer => peer.peerId === peerId
|
peer => peer.peerId === peerId
|
||||||
@ -197,8 +202,6 @@ export function useRoom(
|
|||||||
setNumberOfPeers(newNumberOfPeers)
|
setNumberOfPeers(newNumberOfPeers)
|
||||||
shellContext.setNumberOfPeers(newNumberOfPeers)
|
shellContext.setNumberOfPeers(newNumberOfPeers)
|
||||||
|
|
||||||
handleAudioForLeavingPeer(peerId)
|
|
||||||
|
|
||||||
if (peerExist) {
|
if (peerExist) {
|
||||||
const peerListClone = [...shellContext.peerList]
|
const peerListClone = [...shellContext.peerList]
|
||||||
peerListClone.splice(peerIndex, 1)
|
peerListClone.splice(peerIndex, 1)
|
||||||
@ -206,6 +209,10 @@ export function useRoom(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
peerRoom.onPeerLeave((peerId: string) => {
|
||||||
|
handleAudioForLeavingPeer(peerId)
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
audioDevices,
|
audioDevices,
|
||||||
peerRoom,
|
peerRoom,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useCallback, useState } from 'react'
|
||||||
|
|
||||||
import { ShellContext } from 'contexts/ShellContext'
|
import { ShellContext } from 'contexts/ShellContext'
|
||||||
import { PeerActions } from 'models/network'
|
import { PeerActions } from 'models/network'
|
||||||
@ -65,6 +65,15 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) {
|
|||||||
setPeerAudios({ ...peerAudios, [peerId]: audio })
|
setPeerAudios({ ...peerAudios, [peerId]: audio })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const cleanupAudio = useCallback(() => {
|
||||||
|
if (!audioStream) return
|
||||||
|
|
||||||
|
for (const audioTrack of audioStream.getTracks()) {
|
||||||
|
audioTrack.stop()
|
||||||
|
audioStream.removeTrack(audioTrack)
|
||||||
|
}
|
||||||
|
}, [audioStream])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
;(async () => {
|
;(async () => {
|
||||||
if (isSpeakingToRoom) {
|
if (isSpeakingToRoom) {
|
||||||
@ -83,10 +92,7 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (audioStream) {
|
if (audioStream) {
|
||||||
for (const audioTrack of audioStream.getTracks()) {
|
cleanupAudio()
|
||||||
audioTrack.stop()
|
|
||||||
audioStream.removeTrack(audioTrack)
|
|
||||||
}
|
|
||||||
|
|
||||||
peerRoom.removeStream(audioStream, peerRoom.getPeers())
|
peerRoom.removeStream(audioStream, peerRoom.getPeers())
|
||||||
sendAudioChange(AudioState.STOPPED)
|
sendAudioChange(AudioState.STOPPED)
|
||||||
@ -103,8 +109,15 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) {
|
|||||||
selectedAudioDeviceId,
|
selectedAudioDeviceId,
|
||||||
sendAudioChange,
|
sendAudioChange,
|
||||||
shellContext,
|
shellContext,
|
||||||
|
cleanupAudio,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
cleanupAudio()
|
||||||
|
}
|
||||||
|
}, [cleanupAudio])
|
||||||
|
|
||||||
const handleAudioDeviceSelect = async (audioDevice: MediaDeviceInfo) => {
|
const handleAudioDeviceSelect = async (audioDevice: MediaDeviceInfo) => {
|
||||||
const { deviceId } = audioDevice
|
const { deviceId } = audioDevice
|
||||||
setSelectedAudioDeviceId(deviceId)
|
setSelectedAudioDeviceId(deviceId)
|
||||||
|
@ -6,28 +6,76 @@ export class PeerRoom {
|
|||||||
|
|
||||||
private roomConfig: TorrentRoomConfig & BaseRoomConfig
|
private roomConfig: TorrentRoomConfig & BaseRoomConfig
|
||||||
|
|
||||||
|
private peerJoinHandlers: Set<(peerId: string) => void> = new Set()
|
||||||
|
|
||||||
|
private peerLeaveHandlers: Set<(peerId: string) => void> = new Set()
|
||||||
|
|
||||||
|
private peerStreamHandlers: Set<
|
||||||
|
(stream: MediaStream, peerId: string) => void
|
||||||
|
> = new Set()
|
||||||
|
|
||||||
constructor(config: TorrentRoomConfig & BaseRoomConfig, roomId: string) {
|
constructor(config: TorrentRoomConfig & BaseRoomConfig, roomId: string) {
|
||||||
this.roomConfig = config
|
this.roomConfig = config
|
||||||
this.room = joinRoom(this.roomConfig, roomId)
|
this.room = joinRoom(this.roomConfig, roomId)
|
||||||
|
|
||||||
|
this.room.onPeerJoin((...args) => {
|
||||||
|
for (const peerJoinHandler of this.peerJoinHandlers) {
|
||||||
|
peerJoinHandler(...args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.room.onPeerLeave((...args) => {
|
||||||
|
for (const peerLeaveHandler of this.peerLeaveHandlers) {
|
||||||
|
peerLeaveHandler(...args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.room.onPeerStream((...args) => {
|
||||||
|
for (const peerStreamHandler of this.peerStreamHandlers) {
|
||||||
|
peerStreamHandler(...args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
flush = () => {
|
||||||
|
this.onPeerJoinFlush()
|
||||||
|
this.onPeerLeaveFlush()
|
||||||
|
this.onPeerStreamFlush()
|
||||||
}
|
}
|
||||||
|
|
||||||
leaveRoom = () => {
|
leaveRoom = () => {
|
||||||
if (!this.room) return
|
|
||||||
this.room.leave()
|
this.room.leave()
|
||||||
|
this.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
onPeerJoin: Room['onPeerJoin'] = fn => {
|
onPeerJoin: Room['onPeerJoin'] = fn => {
|
||||||
if (!this.room) return
|
this.peerJoinHandlers.add(fn)
|
||||||
this.room.onPeerJoin((...args) => fn(...args))
|
}
|
||||||
|
|
||||||
|
onPeerJoinFlush = () => {
|
||||||
|
this.peerJoinHandlers.forEach(handler =>
|
||||||
|
this.peerJoinHandlers.delete(handler)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onPeerLeave: Room['onPeerLeave'] = fn => {
|
onPeerLeave: Room['onPeerLeave'] = fn => {
|
||||||
if (!this.room) return
|
this.peerLeaveHandlers.add(fn)
|
||||||
this.room.onPeerLeave((...args) => fn(...args))
|
}
|
||||||
|
|
||||||
|
onPeerLeaveFlush = () => {
|
||||||
|
this.peerLeaveHandlers.forEach(handler =>
|
||||||
|
this.peerLeaveHandlers.delete(handler)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onPeerStream: Room['onPeerStream'] = fn => {
|
onPeerStream: Room['onPeerStream'] = fn => {
|
||||||
this.room.onPeerStream((...args) => fn(...args))
|
this.peerStreamHandlers.add(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPeerStreamFlush = () => {
|
||||||
|
this.peerStreamHandlers.forEach(handler =>
|
||||||
|
this.peerStreamHandlers.delete(handler)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getPeers: Room['getPeers'] = () => {
|
getPeers: Room['getPeers'] = () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es2015",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
Loading…
Reference in New Issue
Block a user