Skip to content

Commit

Permalink
feat: set volume based on global volume
Browse files Browse the repository at this point in the history
* Use GlobalVolumeStore
* Use localStorage to save volume
* Refactor `howlSoundInstance.volume` usage
  • Loading branch information
mateusfg7 committed Aug 22, 2022
1 parent 6e5a730 commit 1bcd29d
Showing 1 changed file with 44 additions and 15 deletions.
59 changes: 44 additions & 15 deletions src/components/Sound/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import { Howl } from 'howler'

import { useGlobalVolumeStore } from '../../stores/GlobalVolumeStore'

import { VolumeController } from '../VolumeController'

export interface ISound {
Expand All @@ -19,28 +21,23 @@ const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
export const Sound: React.FC<ISound> = ({ name, iconFile, audioFile }) => {
const FADE_TIME_MS = 500

const globalVolume = useGlobalVolumeStore(state => state.globalVolume)

const [soundIsActive, setSoundIsActive] = useState(false)
const [howlSoundInstance, setHowlSoundInstance] = useState<Howl | null>(null)
const [currentSoundVolume, setCurrentSoundVolume] = useState(1)

useEffect(() => {
setHowlSoundInstance(
new Howl({
src: `./sounds/${audioFile.name}`,
loop: true,
html5: true
})
)
}, [])
const [localSoundVolume, setLocalSoundVolume] = useState(1)
const [currentSoundVolume, setCurrentSoundVolume] = useState(
localSoundVolume * globalVolume
)

async function toggleSoundState() {
if (howlSoundInstance) {
if (soundIsActive) {
howlSoundInstance.fade(currentSoundVolume, 0, FADE_TIME_MS)
howlSoundInstance.fade(localSoundVolume, 0, FADE_TIME_MS)
await sleep(FADE_TIME_MS)
howlSoundInstance.pause()
} else {
howlSoundInstance.fade(0, currentSoundVolume, FADE_TIME_MS)
howlSoundInstance.fade(0, localSoundVolume, FADE_TIME_MS)
howlSoundInstance.play()
}

Expand All @@ -49,12 +46,43 @@ export const Sound: React.FC<ISound> = ({ name, iconFile, audioFile }) => {
}

function handleSoundVolume(volume: number) {
const calculatedVolume = volume * globalVolume

if (howlSoundInstance) {
howlSoundInstance.volume(volume)
setCurrentSoundVolume(volume)
setCurrentSoundVolume(calculatedVolume)
setLocalSoundVolume(volume)
localStorage.setItem(`${name}-volume`, String(localSoundVolume))
}
}

useEffect(() => {
setHowlSoundInstance(
new Howl({
src: `./sounds/${audioFile.name}`,
loop: true,
html5: true
})
)

if (typeof window !== 'undefined') {
const storageValue = localStorage.getItem(`${name}-volume`)
if (storageValue) setLocalSoundVolume(JSON.parse(storageValue))
else localStorage.setItem(`${name}-volume`, String(localSoundVolume))
}

setCurrentSoundVolume(localSoundVolume * globalVolume)
}, [])

useEffect(() => {
setCurrentSoundVolume(localSoundVolume * globalVolume)
}, [globalVolume])

useEffect(() => {
if (howlSoundInstance) {
howlSoundInstance.volume(currentSoundVolume)
}
}, [currentSoundVolume])

return (
<div
title={name}
Expand All @@ -80,6 +108,7 @@ export const Sound: React.FC<ISound> = ({ name, iconFile, audioFile }) => {
</div>
<VolumeController
state={soundIsActive}
soundNameOnLocalStorage={name}
handleSoundVolume={handleSoundVolume}
/>
</div>
Expand Down

0 comments on commit 1bcd29d

Please sign in to comment.