From 19d0faacccea594631266ee98c3f5bc4320928cb Mon Sep 17 00:00:00 2001 From: Jeremy Kahn Date: Sun, 6 Nov 2022 20:49:48 -0600 Subject: [PATCH] refactor: move video stream data into new room context --- src/components/Room/Room.tsx | 86 +++++++++++++----------- src/components/Room/RoomVideoDisplay.tsx | 19 +++--- src/components/Room/useRoom.ts | 25 +++++-- src/components/Room/useRoomAudio.ts | 16 +++-- src/components/Room/useRoomVideo.ts | 9 +-- src/components/Shell/Shell.tsx | 14 ---- src/contexts/RoomContext.ts | 15 +++++ src/contexts/ShellContext.ts | 8 --- 8 files changed, 105 insertions(+), 87 deletions(-) create mode 100644 src/contexts/RoomContext.ts diff --git a/src/components/Room/Room.tsx b/src/components/Room/Room.tsx index be3f4ec..78757f0 100644 --- a/src/components/Room/Room.tsx +++ b/src/components/Room/Room.tsx @@ -8,6 +8,7 @@ import { v4 as uuid } from 'uuid' import { rtcConfig } from 'config/rtcConfig' import { trackerUrls } from 'config/trackerUrls' +import { RoomContext } from 'contexts/RoomContext' import { MessageForm } from 'components/MessageForm' import { ChatTranscript } from 'components/ChatTranscript' @@ -35,6 +36,7 @@ export function Room({ isMessageSending, messageLog, peerRoom, + roomContextValue, sendMessage, showVideoDisplay, } = useRoom( @@ -56,54 +58,56 @@ export function Room({ } return ( - - {showVideoDisplay && } + - - } - aria-controls="panel1a-content" - id="panel1a-header" - > - - - - - - - - - - + {showVideoDisplay && } + + + } + aria-controls="panel1a-content" + id="panel1a-header" + > + + + + + + + + + + + - + ) } diff --git a/src/components/Room/RoomVideoDisplay.tsx b/src/components/Room/RoomVideoDisplay.tsx index 581d536..1980dae 100644 --- a/src/components/Room/RoomVideoDisplay.tsx +++ b/src/components/Room/RoomVideoDisplay.tsx @@ -1,8 +1,9 @@ import { useContext } from 'react' import Paper from '@mui/material/Paper' -import { Peer } from 'models/chat' +import { RoomContext } from 'contexts/RoomContext' import { ShellContext } from 'contexts/ShellContext' +import { Peer } from 'models/chat' import { PeerVideo } from './PeerVideo' @@ -14,10 +15,14 @@ export interface RoomVideoDisplayProps { export const RoomVideoDisplay = ({ userId }: RoomVideoDisplayProps) => { const shellContext = useContext(ShellContext) + const roomContext = useContext(RoomContext) - const peersWithVideo: PeerWithVideo[] = shellContext.peerList.reduce( + const { peerList } = shellContext + const { peerVideoStreams, selfVideoStream } = roomContext + + const peersWithVideo: PeerWithVideo[] = peerList.reduce( (acc: PeerWithVideo[], peer: Peer) => { - const videoStream = shellContext.peerVideoStreams[peer.peerId] + const videoStream = peerVideoStreams[peer.peerId] if (videoStream) { acc.push({ peer, @@ -45,12 +50,8 @@ export const RoomVideoDisplay = ({ userId }: RoomVideoDisplayProps) => { width: '75%', }} > - {shellContext.selfVideoStream && ( - + {selfVideoStream && ( + )} {peersWithVideo.map(peerWithVideo => ( ( + null + ) + const [peerVideoStreams, setPeerVideoStreams] = useState< + Record + >({}) + + const roomContextValue = useMemo( + () => ({ + selfVideoStream, + setSelfVideoStream, + peerVideoStreams, + setPeerVideoStreams, + }), + [selfVideoStream, setSelfVideoStream, peerVideoStreams, setPeerVideoStreams] + ) + useEffect(() => { return () => { peerRoom.leaveRoom() @@ -200,13 +217,13 @@ export function useRoom( }) const showVideoDisplay = - shellContext.selfVideoStream || - Object.values(shellContext.peerVideoStreams).length > 0 + selfVideoStream || Object.values(peerVideoStreams).length > 0 return { isMessageSending, messageLog, peerRoom, + roomContextValue, sendMessage, showVideoDisplay, } diff --git a/src/components/Room/useRoomAudio.ts b/src/components/Room/useRoomAudio.ts index c32b9d6..9747d48 100644 --- a/src/components/Room/useRoomAudio.ts +++ b/src/components/Room/useRoomAudio.ts @@ -24,6 +24,8 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) { string | null >(null) + const { peerList, setPeerList, setAudioState } = shellContext + useEffect(() => { ;(async () => { if (!audioStream) return @@ -40,7 +42,7 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) { ) receiveAudioChange((audioState, peerId) => { - const newPeerList = shellContext.peerList.map(peer => { + const newPeerList = peerList.map(peer => { const newPeer: Peer = { ...peer } if (peer.peerId === peerId) { @@ -54,7 +56,7 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) { return newPeer }) - shellContext.setPeerList(newPeerList) + setPeerList(newPeerList) }) peerRoom.onPeerStream(PeerStreamType.AUDIO, (stream, peerId) => { @@ -91,7 +93,7 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) { peerRoom.addStream(newSelfStream) sendAudioChange(AudioState.PLAYING) - shellContext.setAudioState(AudioState.PLAYING) + setAudioState(AudioState.PLAYING) setAudioStream(newSelfStream) } } else { @@ -100,20 +102,20 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) { peerRoom.removeStream(audioStream, peerRoom.getPeers()) sendAudioChange(AudioState.STOPPED) - shellContext.setAudioState(AudioState.STOPPED) + setAudioState(AudioState.STOPPED) setAudioStream(null) } } })() }, [ + audioStream, + cleanupAudio, isSpeakingToRoom, peerAudios, peerRoom, - audioStream, selectedAudioDeviceId, sendAudioChange, - shellContext, - cleanupAudio, + setAudioState, ]) useEffect(() => { diff --git a/src/components/Room/useRoomVideo.ts b/src/components/Room/useRoomVideo.ts index 2aa570c..252381d 100644 --- a/src/components/Room/useRoomVideo.ts +++ b/src/components/Room/useRoomVideo.ts @@ -1,5 +1,6 @@ import { useContext, useEffect, useCallback, useState } from 'react' +import { RoomContext } from 'contexts/RoomContext' import { ShellContext } from 'contexts/ShellContext' import { PeerActions } from 'models/network' import { VideoState, Peer } from 'models/chat' @@ -13,21 +14,21 @@ interface UseRoomVideoConfig { export function useRoomVideo({ peerRoom }: UseRoomVideoConfig) { const shellContext = useContext(ShellContext) + const roomContext = useContext(RoomContext) const [isCameraEnabled, setIsCameraEnabled] = useState(false) const [videoDevices, setVideoDevices] = useState([]) const [selectedVideoDeviceId, setSelectedVideoDeviceId] = useState< string | null >(null) + const { peerList, setPeerList, setVideoState } = shellContext + const { - peerList, peerVideoStreams, selfVideoStream, - setPeerList, setPeerVideoStreams, setSelfVideoStream, - setVideoState, - } = shellContext + } = roomContext useEffect(() => { ;(async () => { diff --git a/src/components/Shell/Shell.tsx b/src/components/Shell/Shell.tsx index 554957b..ea617c0 100644 --- a/src/components/Shell/Shell.tsx +++ b/src/components/Shell/Shell.tsx @@ -46,12 +46,6 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => { const [tabHasFocus, setTabHasFocus] = useState(true) const [audioState, setAudioState] = useState(AudioState.STOPPED) const [videoState, setVideoState] = useState(VideoState.STOPPED) - const [selfVideoStream, setSelfVideoStream] = useState( - null - ) - const [peerVideoStreams, setPeerVideoStreams] = useState< - Record - >({}) const showAlert = useCallback< (message: string, options?: AlertOptions) => void @@ -78,10 +72,6 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => { setAudioState, videoState, setVideoState, - selfVideoStream, - setSelfVideoStream, - peerVideoStreams, - setPeerVideoStreams, }), [ isPeerListOpen, @@ -97,10 +87,6 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => { setAudioState, videoState, setVideoState, - selfVideoStream, - setSelfVideoStream, - peerVideoStreams, - setPeerVideoStreams, ] ) diff --git a/src/contexts/RoomContext.ts b/src/contexts/RoomContext.ts new file mode 100644 index 0000000..6261025 --- /dev/null +++ b/src/contexts/RoomContext.ts @@ -0,0 +1,15 @@ +import { createContext, Dispatch, SetStateAction } from 'react' + +interface RoomContextProps { + selfVideoStream: MediaStream | null + setSelfVideoStream: Dispatch> + peerVideoStreams: Record + setPeerVideoStreams: Dispatch>> +} + +export const RoomContext = createContext({ + selfVideoStream: null, + setSelfVideoStream: () => {}, + peerVideoStreams: {}, + setPeerVideoStreams: () => {}, +}) diff --git a/src/contexts/ShellContext.ts b/src/contexts/ShellContext.ts index 3c777d2..46e3b49 100644 --- a/src/contexts/ShellContext.ts +++ b/src/contexts/ShellContext.ts @@ -18,10 +18,6 @@ interface ShellContextProps { setAudioState: Dispatch> videoState: VideoState setVideoState: Dispatch> - selfVideoStream: MediaStream | null - setSelfVideoStream: Dispatch> - peerVideoStreams: Record - setPeerVideoStreams: Dispatch>> } export const ShellContext = createContext({ @@ -39,8 +35,4 @@ export const ShellContext = createContext({ setAudioState: () => {}, videoState: VideoState.STOPPED, setVideoState: () => {}, - selfVideoStream: null, - setSelfVideoStream: () => {}, - peerVideoStreams: {}, - setPeerVideoStreams: () => {}, })