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: () => {},
})