diff --git a/src/components/Room/Room.tsx b/src/components/Room/Room.tsx index 265d779..f8c100c 100644 --- a/src/components/Room/Room.tsx +++ b/src/components/Room/Room.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useRef, useState } from 'react' +import { useContext, useEffect, useState } from 'react' import { v4 as uuid } from 'uuid' import Box from '@mui/material/Box' import Divider from '@mui/material/Divider' @@ -14,6 +14,7 @@ import { MessageForm } from 'components/MessageForm' import { ChatTranscript } from 'components/ChatTranscript' import { getPeerName } from 'components/PeerNameDisplay' import { NotificationService } from 'services/Notification' +import { Audio } from 'services/Audio' export interface RoomProps { appId?: string @@ -35,8 +36,9 @@ export function Room({ const [messageLog, setMessageLog] = useState< Array >([]) - const [audioContext] = useState(() => new AudioContext()) - const audioBufferContainer = useRef(null) + const [newMessageAudio] = useState( + () => new Audio(process.env.PUBLIC_URL + '/sounds/new-message.aac') + ) const peerRoom = usePeerRoom( { @@ -47,23 +49,6 @@ export function Room({ roomId ) - // TODO: Move audio logic to a service - useEffect(() => { - ;(async () => { - try { - const response = await fetch( - process.env.PUBLIC_URL + '/sounds/new-message.aac' - ) - const arrayBuffer = await response.arrayBuffer() - audioBufferContainer.current = await audioContext.decodeAudioData( - arrayBuffer - ) - } catch (e) { - console.error(e) - } - })() - }, [audioBufferContainer, audioContext]) - useEffect(() => { shellContext.setDoShowPeers(true) @@ -123,7 +108,7 @@ export function Room({ if (!shellContext.tabHasFocus) { if (userSettings.playSoundOnNewMessage) { - playNewMessageSound() + newMessageAudio.play() } if (userSettings.showNotificationOnNewMessage) { @@ -136,17 +121,6 @@ export function Room({ setMessageLog([...messageLog, { ...message, timeReceived: Date.now() }]) }) - const playNewMessageSound = () => { - if (!audioBufferContainer.current) { - console.error('Audio buffer not available') - return - } - const audioSource = audioContext.createBufferSource() - audioSource.buffer = audioBufferContainer.current - audioSource.connect(audioContext.destination) - audioSource.start() - } - const handleMessageSubmit = async (message: string) => { await performMessageSend(message) } diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index 96aa41b..f0d70f9 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -1,6 +1,5 @@ /// -// TODO: Contribute this to Trystero declare module 'trystero' { export type RoomConfig = BaseRoomConfig & (BitTorrentRoomConfig | FirebaseRoomConfig | IpfsRoomConfig) diff --git a/src/services/Audio/Audio.ts b/src/services/Audio/Audio.ts new file mode 100644 index 0000000..d0ab8bc --- /dev/null +++ b/src/services/Audio/Audio.ts @@ -0,0 +1,33 @@ +export class Audio { + private audioContext: AudioContext = new AudioContext() + + private audioBuffer: AudioBuffer | null = null + + constructor(audioDataUrl?: string) { + if (audioDataUrl) { + this.load(audioDataUrl) + } + } + + load = async (audioDataUrl: string) => { + try { + const response = await fetch(audioDataUrl) + const arrayBuffer = await response.arrayBuffer() + this.audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer) + } catch (e) { + console.error(e) + } + } + + play = () => { + if (this.audioBuffer === null) { + console.error('Audio buffer not available') + return + } + + const audioSource = this.audioContext.createBufferSource() + audioSource.buffer = this.audioBuffer + audioSource.connect(this.audioContext.destination) + audioSource.start() + } +} diff --git a/src/services/Audio/index.ts b/src/services/Audio/index.ts new file mode 100644 index 0000000..c44b11b --- /dev/null +++ b/src/services/Audio/index.ts @@ -0,0 +1 @@ +export * from './Audio'