diff --git a/src/components/AudioVolume/AudioVolume.tsx b/src/components/AudioVolume/AudioVolume.tsx new file mode 100644 index 0000000..bcddfbc --- /dev/null +++ b/src/components/AudioVolume/AudioVolume.tsx @@ -0,0 +1,58 @@ +import { useState, useEffect } from 'react' +import Slider from '@mui/material/Slider' +import Box from '@mui/material/Box' +import ListItemIcon from '@mui/material/ListItemIcon' +import VolumeUp from '@mui/icons-material/VolumeUp' +import VolumeDown from '@mui/icons-material/VolumeDown' +import VolumeMute from '@mui/icons-material/VolumeMute' + +interface AudioVolumeProps { + audioEl: HTMLAudioElement +} + +export const AudioVolume = ({ audioEl }: AudioVolumeProps) => { + const [audioVolume, setAudioVolume] = useState(audioEl.volume) + + useEffect(() => { + audioEl.volume = audioVolume + }, [audioEl, audioVolume]) + + const handleIconClick = () => { + if (audioVolume === 0) { + setAudioVolume(1) + } else { + setAudioVolume(0) + } + } + + const handleSliderChange = (_event: Event, value: number | number[]) => { + value = Array.isArray(value) ? value[0] : value + setAudioVolume(value / 100) + } + + const formatLabelValue = () => `${Math.round(audioVolume * 100)}%` + + let VolumeIcon = VolumeUp + + if (audioVolume === 0) { + VolumeIcon = VolumeMute + } else if (audioVolume < 0.5) { + VolumeIcon = VolumeDown + } + + return ( + + + + + + + ) +} diff --git a/src/components/AudioVolume/index.ts b/src/components/AudioVolume/index.ts new file mode 100644 index 0000000..8323f38 --- /dev/null +++ b/src/components/AudioVolume/index.ts @@ -0,0 +1 @@ +export * from './AudioVolume' diff --git a/src/components/Room/useRoomAudio.ts b/src/components/Room/useRoomAudio.ts index 9747d48..1db7590 100644 --- a/src/components/Room/useRoomAudio.ts +++ b/src/components/Room/useRoomAudio.ts @@ -14,9 +14,6 @@ interface UseRoomAudioConfig { export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) { const shellContext = useContext(ShellContext) const [isSpeakingToRoom, setIsSpeakingToRoom] = useState(false) - const [peerAudios, setPeerAudios] = useState< - Record - >({}) const [audioStream, setAudioStream] = useState() const [audioDevices, setAudioDevices] = useState([]) @@ -24,7 +21,8 @@ export function useRoomAudio({ peerRoom }: UseRoomAudioConfig) { string | null >(null) - const { peerList, setPeerList, setAudioState } = shellContext + const { peerList, setPeerList, setAudioState, peerAudios, setPeerAudios } = + shellContext useEffect(() => { ;(async () => { diff --git a/src/components/Shell/PeerList.tsx b/src/components/Shell/PeerList.tsx index 6e21960..5b130d8 100644 --- a/src/components/Shell/PeerList.tsx +++ b/src/components/Shell/PeerList.tsx @@ -10,6 +10,7 @@ import VolumeUp from '@mui/icons-material/VolumeUp' import ListItem from '@mui/material/ListItem' import { PeerListHeader } from 'components/Shell/PeerListHeader' +import { AudioVolume } from 'components/AudioVolume' import { PeerNameDisplay } from 'components/PeerNameDisplay' import { AudioState, Peer } from 'models/chat' @@ -23,6 +24,7 @@ export interface PeerListProps extends PropsWithChildren { onPeerListClose: () => void peerList: Peer[] audioState: AudioState + peerAudios: Record } export const PeerList = ({ @@ -31,6 +33,7 @@ export const PeerList = ({ onPeerListClose, peerList, audioState, + peerAudios, }: PeerListProps) => { return ( - + {audioState === AudioState.PLAYING && ( @@ -68,20 +71,17 @@ export const PeerList = ({ {peerList.map((peer: Peer) => ( - + {peer.userId} + {peer.peerId in peerAudios && ( + + )} - {peer.audioState === AudioState.PLAYING && ( - - - - )} ))} - ) } diff --git a/src/components/Shell/Shell.tsx b/src/components/Shell/Shell.tsx index 6ffe550..d93b431 100644 --- a/src/components/Shell/Shell.tsx +++ b/src/components/Shell/Shell.tsx @@ -56,6 +56,9 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => { const [screenState, setScreenState] = useState( ScreenShareState.NOT_SHARING ) + const [peerAudios, setPeerAudios] = useState< + Record + >({}) const showAlert = useCallback< (message: string, options?: AlertOptions) => void >((message, options) => { @@ -89,6 +92,8 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => { setVideoState, screenState, setScreenState, + peerAudios, + setPeerAudios, }), [ isPeerListOpen, @@ -112,6 +117,8 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => { setVideoState, screenState, setScreenState, + peerAudios, + setPeerAudios, ] ) @@ -322,6 +329,7 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => { onPeerListClose={handlePeerListClick} peerList={peerList} audioState={audioState} + peerAudios={peerAudios} /> > screenState: ScreenShareState setScreenState: Dispatch> + peerAudios: Record + setPeerAudios: Dispatch>> } export const ShellContext = createContext({ @@ -51,4 +53,6 @@ export const ShellContext = createContext({ setVideoState: () => {}, screenState: ScreenShareState.NOT_SHARING, setScreenState: () => {}, + peerAudios: {}, + setPeerAudios: () => {}, })